Je connais des conteneurs STL comme vecteur code> copie l'objet quand il est ajouté.
Push_back CODE> La méthode ressemble à:
struct Foo
{
Foo()
{
std::cout << "Inside Foo constructor" << std::endl;
}
Foo(const Foo& f)
{
std::cout << "inside copy constructor" << std::endl;
}
};
Foo f;
std::vector<Foo> foos;
foos.push_back(f);
3 Réponses :
Il utilise probablement "Placement Le constructeur de copie note que Voici comment Gnu's LibstDC ++ fait-il , mais je doute que ce sera très éclairant. Il y a un allocator (le deuxième argument de modèle à Nouveau code>" pour construire l'objet dans sa matrice interne. Placement
Nouveau code> n'alloue pas de mémoire; Cela place simplement l'objet où vous spécifiez et appelle le constructeur. La syntaxe est
nouvelle (adresse) (constructor_arguments) code>.
T :: t (t const &) code> est appelé pour créer la copie en place . Quelque chose comme ça (simplifié): p>
t code> doit avoir un constructeur de copie pour que cela fonctionne. Par défaut (si vous ne faites rien), il en reçoit un gratuitement. Si vous le définissez explicitement, il doit être
public code> pour
vecteur
vecteur code>) qui le rend moins simple. P> p>
Ceci est correct quand T a un constructeur sans paramètre. Mais que se passera-t-il quand il a un constructeur paramétré? Comment vecteur peut-il initialiser un nouvel objet?
C'est bon quand T a un Copy Constructor i>. Ce qui est fait, par défaut, et si vous le mettez en train de le mettre en œuvre, sauf si vous avez explicitement fait privé code> ou
protégé code>.
Merci. Je vais enquêter plus loin.
Votre explication est claire. Je me demande pourquoi ils n'ont pas de signature comme push_back (t const article) code> et en évitant le placement nouveau.
Cela ferait une copie de l'élément lorsqu'elle sera transmise à la fonction (car elle est transmise), que la version pass par référence évite. Il pourrait éviter le placement nouveau code> à l'aide de l'opérateur
= code>, mais cela nécessiterait qu'il existe déjà un objet initialisé à cet endroit (pour appeler
opérateur = code > ON) et nécessite donc
t code> pour avoir un constructeur par défaut.
L'autre avantage d'utiliser le placement nouveau est que l'espace inutilisé que le vecteur a alloué, mais qui n'a pas encore été rempli, ne doit pas être initialisé du tout. Il s'agit d'une petite optimisation si le constructeur par défaut de T existe et ne fait pas grand chose, mais une différence significative si le constructeur par défaut de T fait beaucoup de travail, ou a des effets secondaires. Et comme le souligne Thomas, il permet de ne pas avoir de constructeur de no-args du tout.
Il utilise le placement nouvel opérateur et la copie-latrose-le construit en mémoire unitalisé;
Le placement nouveau crée un nouvel élément à une adresse spécifiée en mémoire, dans le boîtier de vecteur, l'extrémité actuelle (); P> regarder http://spotep.com/dev/devector .h qui a un code assez clair (par opposition à la plupart des implémentations stl). P> p>
Le SDK C ++ prend toujours Dans votre cas si elle prend const t & code> comme paramètre de fonction pour l'efficacité. P>
t code> comme paramètre, l'action de copie sera effectuée deux fois, une pour la transmettre à la fonction
push_back (f) code>, un pour l'ajout interne au conteneur. Et en prenant
const t & code> comme paramètre, une seule copie n'est nécessaire! P>