Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Langage
Langage Langage C++, Programmation Orientée Objet, Templates, etc. Avant de poster : FAQ C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 27/12/2012, 16h07   #1
r0d
Expert Confirmé Sénior
 
Inscription : août 2004
Messages : 3 665
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : août 2004
Messages : 3 665
Points : 4 421
Points : 4 421
Par défaut vector et copy constructor

Bonjour, prenons le code suivant:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <vector>
#include <string>
 
using namespace std;
 
struct Foo
{
	Foo( const string & name = "unknown" ) : name( name ) { cout << "ctor" << endl; }
	Foo( const Foo & other ) : name( other.name ) { cout << "copy ctor" << endl; }
	Foo & operator = ( const Foo & other ) { name = other.name; cout << "operator =" << endl; }
 
	string name;
};
 
main()
{
	vector< Foo > v;
	v.push_back( Foo() );
	getchar();
}
L'ouput donne:
Citation:
ctor
copy ctor
Ce qui signifie que le constructeur de copie de Foo est appelé lors du push_back.

Pourquoi fait-il cette copie? Comment l'éviter (étant entendu que l'on ne connait pas à l'avance le nombre d'éléments que l'on va mettre dans le vecteur)?
r0d est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 16h25   #2
Ehonn
Membre éprouvé
 
Étudiant
Inscription : février 2012
Messages : 206
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2012
Messages : 206
Points : 438
Points : 438
std::vector gère la vie de ses objets et en fait donc une copie.
De plus, std::vector gère un tableau dynamique. Lorsque la taille du tableau est trop petite, il en alloue un nouveau et recopie tous les éléments.

Il faut utiliser un std::vector de pointeurs intelligents.
Ehonn est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 16h26   #3
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 551
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 551
Points : 2 960
Points : 2 960
Ici:

Tu as

qui construit l'objet, qui est un objet temporaire.

Puis l'objet temporaire est passe a push_back qui copie cet objet dans l'array que le vector gere.

Par contre, il me semble que certains compilos vont eliminer la copie si tu compile en optimise (pas en Debug). Cela dis ce n'estpas garanti.

En C++03, ce n'est pas possible de garantir qu'il ny aura pas cette copie.

En revanche, C++11 offre une solution.

Code :
v.emplace_back( /* arguments du constructeur de Foo ici */ );
En gros ca construit l'objet directement dans l'array geree par le vector, en lui passant les arguments de construction que tu lui files (ici, constructeur par defaut, pas d'arguments).

Ca resouds le probleme. Mais il faut un compilateur et une bibliotheque standard C++11.
Klaim est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 27/12/2012, 16h45   #4
r0d
Expert Confirmé Sénior
 
Inscription : août 2004
Messages : 3 665
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : août 2004
Messages : 3 665
Points : 4 421
Points : 4 421
Citation:
Envoyé par Klaim Voir le message
En revanche, C++11 offre une solution.

Code :
v.emplace_back( /* arguments du constructeur de Foo ici */ );
ça semble en effet résoudre le problème, merci

Je viens de tester sur vs 2010, mais visiblement il y a une limitation: emplace_back prend un et un seul argument (donc pas possible d'utiliser directement avec des constructeurs prenant zero ou plusieurs arguments). Limitation facile à contourner, mais limitation tout de même. D'ailleurs, peut-être que couplé avec une inplace_factory de boost, ça pourrait donner des trucs assez magiques
r0d est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 19h21   #5
backlash
Membre habitué
 
Inscription : mars 2010
Messages : 114
Détails du profil
Informations forums :
Inscription : mars 2010
Messages : 114
Points : 119
Points : 119
Citation:
emplace_back prend un et un seul argument
Heu, non, le prototype de emplace_back est le suivant :
Code :
1
2
template< class... Args >
void emplace_back( Args&&... args );
backlash est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 19h49   #6
Arzar
Membre Expert
 
Inscription : mai 2008
Messages : 937
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 937
Points : 1 783
Points : 1 783
Dans le standard emplace_back peut prendre un nombre arbitraire d'argument mais, sur vs2010, vu l’absence de template variadique microsoft a implémenté une version restreinte d'emplace_back qui ne prend qu'un seul argument. (c'est un peu mieux sur vs2012 où l'on peut aller jusqu'à 4 arguments)
Arzar est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 11h48.


 
 
 
 
Partenaires

Hébergement Web