Interdire copie et std::vector

Le
philippe.lrx
Bonjour,

J'ai eu un mal de chien a repérer un bug lié à une copie d'objet qui
n'aurait jamais du être faite et qui provoquait des plantages.
Le problème c'est que je ne sais pas comment empêcher la copie de
l'objet sauf en passant par un pointeur.
Voici un exemple reproduisant mon problème :
class A
{
public:
class B
{
public:
B( std::string const& n )
: n_( n )
{}

std::string get() const { return n_; }

private:
friend A;
B( B const& copy )
: n_( copy.n_ )
{}

B& operator==( B const& copy )
{
n_ = copy.n_;
return *this;
}

std::string n_;
};
typedef std::vector<B> Bvector;

void add( std::string const& n )
{
bvector_.push_back( B( n ) ); // besoin d'une copie.
}

B const& getB( size_t i ) const
{
return bvector_[i];
}

private:
Bvector bvector_;
};


int main()
{
A a;
// étape 1
a.add( "string 1" );
a.add( "string 2" );

//étape 2
A::B const& b1 = a.getB( 0 );
A::B const b2 = a.getB( 1 ); // interdire ca !

std::cout << "b1 = " << b1.get() << ", b2 = " << b2.get() << '';
return 0;
}

Est ce qu'il existe une solution pour que add puisse faire sa copie ou
suis je obligé de passer par des pointeurs sur B ?

Merci.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fabien LE LEZ
Le #19010321
On Sun, 29 Mar 2009 22:40:52 -0700 (PDT), :

B& operator==( B const& copy )



== est un opérateur de comparaison, qui doit renvoyer un "bool".
Tu voulais sans doute écrire
B& operator =
(un seul '=').

Par ailleurs, le mot "copy" ici me paraît douteux. Un nom comme
"source" me semble plus adéquat.
James Kanze
Le #19010801
On Mar 30, 7:40 am, wrote:

J'ai eu un mal de chien a repérer un bug lié à une copie
d'objet qui n'aurait jamais du être faite et qui provoquait
des plantages.



Si un objet ne doit pas être copié, la solution habituelle est
de déclarer son constructeur de copie (et son opérateur
d'affectation aussi, si on ne veut pas le supporter non plus)
privé, et de n'en fournir pas d'implémentation. En revanche, de
tels objets ne peuvent pas se trouver dans une collection
standard.

Le problème c'est que je ne sais pas comment empêcher la copie
de l'objet sauf en passant par un pointeur.



Il y a deux choses : pour empêcher la copie, tu déclares le
constructeur de copie (et l'affectation) privés. Pour utiliser
un objet qui ne supporte pas la copie dans une collection, il
faut effectivement passer par un pointeur ; les collections
font toutes des copies.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
philippe.lrx
Le #19010921
On 30 mar, 08:46, Fabien LE LEZ
On Sun, 29 Mar 2009 22:40:52 -0700 (PDT), :

>        B& operator==( B const& copy )

== est un opérateur de comparaison, qui doit renvoyer un "bool".
Tu voulais sans doute écrire
        B& operator =
(un seul '=').



Exacte.
Par ailleurs, le mot "copy" ici me paraît douteux. Un nom comme
"source" me semble plus adéquat.


Oui, maintenant que tu le dis.
philippe.lrx
Le #19010911
On 30 mar, 09:32, James Kanze
On Mar 30, 7:40 am, wrote:



[..]
Il y a deux choses : pour empêcher la copie, tu déclares le
constructeur de copie (et l'affectation) privés. Pour utiliser
un objet qui ne supporte pas la copie dans une collection, il
faut effectivement passer par un pointeur ; les collections
font toutes des copies.



Merci pour la réponse.
Mickaël Wolff
Le #19024691
James Kanze wrote:

Si un objet ne doit pas être copié, la solution habituelle est
de déclarer son constructeur de copie (et son opérateur
d'affectation aussi, si on ne veut pas le supporter non plus)
privé, et de n'en fournir pas d'implémentation. En revanche, de
tels objets ne peuvent pas se trouver dans une collection
standard.



Tout à fait. Ce qui peut ^etre une bonne occasion de parler de
boost::ref, qui permet d'utiliser des objets non-copiables dans les
conteneurs standards. Ca suppose une dépendance supplémentaire cependant.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Publicité
Poster une réponse
Anonyme