Les différences de l'utilisation de “const cv::Mat &”, “cv::Mat &”, “cv::Mat” ou “const cv::Mat” comme les paramètres de la fonction?

J'ai cherché à fond et n'ont pas trouvé une réponse simple à cette.

Passant opencv matrices (cv::Mat) que les arguments d'une fonction, nous sommes le passage d'un pointeur intelligent. Tout changement que nous faisons à l'entrée de la matrice à l'intérieur de la fonction modifie la matrice à l'extérieur de la portée de la fonction en tant que bien.

J'ai lu que par le passage d'une matrice comme const de référence, il n'est pas modifié à l'intérieur de la fonction. Mais un simple exemple montre qu'il n':

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";
}

Clairement, A est altérée, même si il est envoyé comme un const cv::Mat&.

Cela ne m'étonne pas qu'au sein de la fonction I2 est une simple copie de I1's pointeur intelligent et ainsi tout changement dans I2 va modifier I1.

Ce n'déflecteur moi, c'est que je ne comprends pas quelle différence existe entre l'envoi de cv::Mat, const cv::Mat, const cv::Mat& ou cv::Mat& que les arguments d'une fonction.

Je sais comment faire pour remplacer ce (en remplacement de Output = Input; avec Output = Input.clone(); permettrait de résoudre le problème), mais ne comprends toujours pas le ci-dessus mentionné différence.

Merci les gars!

  • nice pathologique des exemples 😉
  • pas sûr à 100% mais je pense que cv::Mat est une "tête" de la classe qui détient certains des octets de l'information, afin cv::Mat & comme paramètre n'a pas besoin pour copier l'en-tête. Const vs non-const peut montrer à l'utilisateur que les éléments de la matrice ne sont PAS DESTINÉS à être modifié lors de l'appel de la fonction, tandis que la lecture de l'en-tête/documentation.
  • Si vous pensez que le Mat's que les en-têtes autour de quelques données, vous pouvez voir comment vous pouvez copier l'en-tête et ainsi de modifier les données via une autre voie, mais vous ne pouvez pas modifier la "tête" même si vous avez passé comme const. Par exemple, vous ne pouvez pas modifier le nombre de lignes, de colonnes ou de type de Input et si vous essayez de le faire via Output, il compile mais ne changerait pas Input, il serait juste de réaffecter Output à de nouvelles données.
  • Si votre fonction avait été void sillyFunc(const cv::Mat* Input, cv::Mat* Output), le compilateur ne pas vous laisser jeter un const cv::Mat* dans un cv::Mat*. Je ne sais pas pourquoi ce n'est pas le cas avec des références...
  • Je ne suis pas sûr de ce que la question est de savoir, mais si vous vous demandez pourquoi vous obtenez ce contre-intuitive, le comportement, la réponse est que à un certain moment, quelqu'un a décidé que ce serait une bonne idée de la conception cv::Mat de cette façon.
  • J'ai oublié de mentionner que j'ai vu des codes en ligne où const cv::Mat& a été utilisé comme un lisibles à l'aide de rappeler le programmeur qu'il n'est pas censé être changé à l'intérieur de la fonction.
  • Ce n'est pas de la coulée références; c'est à l'aide de valeurs, ils se réfèrent.
  • Mis à part le fait que je pourrais avoir abusé du mot cast, pourquoi le compilateur permet Output = Input; quand Input est const référence et Output un non-const de référence, mais pas quand Input est un pointeur const et Output un non-const pointeur?
  • Parce que l'expression équivalente avec des pointeurs serait *Sortie = *Entrée, qui est valide. La mission est de travailler sur les valeurs visées à, pas les références elles-mêmes.

InformationsquelleAutor CV_User | 2014-05-05