2011-11-25 4 views
1

J'essaie de comprendre le constructeur utilisé dans une classe implémentée dans une bibliothèque que j'utilise. Les éléments clés de la classe SequenceAnalyzer ressemblent:Construction d'une classe via des références à des objets

class SequenceAnalyzer { 
    protected: 
    std::vector<cv::Mat> images_; 

    public: 
    SequenceAnalyzer(std::vector<cv::Mat> *images = NULL) 
    { 
     if (images != NULL) 
      images_ = (*images); 
    } 

}; 

Lors de la construction d'une instance de cette classe dans mon principal, je passe une référence à un vecteur:

std::vector<cv::Mat> myImages; 
SequenceAnalyzer se(&myImages); 

maintenant passer dans mes images par référence passé leur emplacement en mémoire à la classe. Mais ma compréhension de l'opérateur (* images) signifie que leur adresse a été déréférencée et que l'opérateur = copie alors le contenu.

Y at-il un avantage à faire passer myImages dans la classe de cette manière? Pourquoi les pointeurs sont-ils utilisés en premier lieu si cela ne se termine pas en copie de sauvegarde sauvegardée?

+2

Je ne vois aucune référence ici . –

+0

Si vous voulez dire la différence entre les références et les pointeurs, je crains que ce soit un sujet flou pour moi. Si vous voulez dire de quelle bibliothèque je parle, c'est le [projet de bibliothèque OpenCV Structure from Motion] (http://code.google.com/p/gsoc2011sfm/). – Chris

+0

Vous le passez comme pointeur sur l'objet 'vector ' myImages. – Praveen

Répondre

1

Il n'y a aucun avantage. Je voudrais écrire le même code que:

SequenceAnalyzer(const std::vector<cv::Mat>& images = std::vector<cv::Mat>()) : 
    images_(images) 
{ 
} 

Maintenant, je ne pas besoin de vous soucier de pointeurs:

std::vector<cv::Mat> myImages; 
SequenceAnalyzer se(myImages); 
+0

Je pense qu'il demande de passer par référence-_ ou_-pointeur _vs_ par valeur, pas entre les deux. –

+0

@ TomalakGeret'kal: peut-être, mais ce n'est pas clair à la question. – ybungalobill

+1

Quant à la référence vs pointeur, mon impression était que C++ avait tendance à préférer utiliser des références dans les définitions de fonctions, plutôt que des pointeurs, mais c'est juste mon impression. Le code ci-dessus semble certainement une option plus attrayante que l'original. – Chris

0

passage de paramètres par pointeur (ou référence) au lieu de la valeur par copie temporaire éviter. Ainsi, la copie est effectuée uniquement en cas de besoin, et non lors de son passage en paramètre. Un autre avantage est que vous pouvez avoir un paramètre par défaut NULL, sans créer un constructeur par défaut. Dans ce cas, le constructeur implicite par défaut devrait faire de même.

Une façon plus élégante peut être ceci:

SequenceAnalyzer(const std::vector<cv::Mat>& images) { 
    images_ = images; 
} 

Aucune copie temporaire (vous passez par référence) et qui utilise c'est sûr des images modifiées coutume.

+1

Cependant, la façon dont ils le font dans le message original est vraiment un mauvais style C++ :) –

+0

Vous pouvez également avoir un paramètre par défaut avec la référence. –

+0

@ TomalakGeret'kal oui, mais il doit être un objet instancié. –

1

Lors de la construction d'une instance de cette classe dans mon principal, je passe une référence à un vecteur:

std::vector<cv::Mat> myImages; 
SequenceAnalyzer se(&myImages); 

Non, vous ne le faites pas.

& sur un type indique un type de référence; & sur une expression est l'opérateur "adresse-de" et donne un pointeur! C'est pourquoi votre constructeur accepte un pointeur, sinon cela ne fonctionnerait pas. Maintenant

passant dans mes images par référence [pointeur] passé leur emplacement en mémoire à la classe. Mais ma compréhension de l'opérateur (*images) signifie que leur adresse a été déréférencée et donc l'opérateur = puis copie le contenu.

Correct.

Y at-il un avantage à faire passer myImages dans la classe de cette manière ? Pourquoi les pointeurs sont-ils utilisés en premier lieu si cela ne se termine pas en de toute façon?

On peut supposer que le programmeur voulait éviter le vecteur copié deux fois (une fois pour l'argument et encore pour le stockage en tant que membre). Il est inhabituel de faire cela avec un pointeur plutôt qu'une référence, cependant.


j'aurais plutôt écrit:

class SequenceAnalyzer { 
    protected: 
    std::vector<cv::Mat> images_; 

    public: 
    SequenceAnalyzer(const std::vector<cv::Mat>& images = std::vector<cv::Mat>()) 
     : images_(images) {}; 
}; 

Maintenant que vous avez votre paramètre de référence, votre défaut, et vous êtes initialisant correctement.

0

Il peut être utile de savoir que même si vous copiez le vecteur, vous ne copiez que les en-têtes d'image (structure contenant le type, la largeur, la hauteur, etc.). Les objets Mat encapsulent un pointeur intelligent vers les données, donc une copie profonde des données d'image ne se produit que lors de l'appel de fonctions spécifiques (Mat :: copyTo(), Mat :: clone())

Questions connexes