Я тщательно искал и не нашел прямого ответа на этот вопрос.
Передавая матрицы opencv (cv::Mat
) в качестве аргументов функции, мы передаем интеллектуальный указатель. Любое изменение, которое мы вносим во входную матрицу внутри функции, также изменяет матрицу за пределами области действия функции.
Я читал, что при передаче матрицы в качестве константной ссылки она не изменяется внутри функции. Но простой пример показывает, что это так:
void sillyFunc(const cv::Mat& Input, cv::Mat& Output){
Output = Input;
Output += 1;
}
int main( int argc, char** argv ){
cv::Mat A = cv::Mat::ones(3,3,CV_8U);
std::cout<<"A = \n"<<A<<"\n\n";
cv::Mat B;
sillyFunc(A,B);
std::cout<<"A = \n"<<A<<"\n\n";
std::cout<<"B = \n"<<B<<"\n\n";
}
Ясно, что A
изменено, даже если оно отправлено как const cv::Mat&
.
Меня это не удивляет, так как функция I2
является простой копией интеллектуального указателя I1
, и поэтому любое изменение в I2
изменит I1
.
Что меня сбивает с толку, так это то, что я не понимаю, какая практическая разница существует между отправкой cv::Mat
, const cv::Mat
, const cv::Mat&
или cv::Mat&
в качестве аргументов функции.
Я знаю, как переопределить это (замена Output = Input;
на Output = Input.clone();
решит проблему), но до сих пор не понимаю вышеупомянутой разницы.
Спасибо ребята!
cv::Mat
- это класс заголовка, который содержит несколько байтов информации, поэтомуcv::Mat &
в качестве параметра не нужно копировать этот заголовок. Const vs non-const может показать пользователю, что элементы матрицы НЕ ПРЕДНАЗНАЧЕНЫ для изменения при вызове функции при чтении заголовка/документации. - person Micka   schedule 05.05.2014Mat
как о заголовках для некоторых данных, вы можете увидеть, как вы можете скопировать заголовок и, таким образом, изменить данные по другому маршруту, однако вы не можете изменить сам заголовок, если вы передали какconst
. Например, вы не можете изменить количество строк, столбцов или типInput
, и если вы попытаетесь сделать это черезOutput
, он скомпилируется, но не изменитInput
, он просто переназначитOutput
на какие-то новые данные. - person Roger Rowland   schedule 05.05.2014void sillyFunc(const cv::Mat* Input, cv::Mat* Output)
, компилятор не позволил бы вам преобразоватьconst cv::Mat*
вcv::Mat*
. Не уверен, почему это не относится к ссылкам... - person BConic   schedule 05.05.2014cv::Mat
таким образом. - person juanchopanza   schedule 05.05.2014cast
, почему компилятор разрешаетOutput = Input;
, когдаInput
является константной ссылкой, аOutput
неконстантной ссылкой, но не когдаInput
является константным указателем, аOutput
неконстантным указателем. ? - person BConic   schedule 05.05.2014