Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Interdire copie et std::vector

5 réponses
Avatar
philippe.lrx
Bonjour,

J'ai eu un mal de chien a rep=E9rer un bug li=E9 =E0 une copie d'objet qui
n'aurait jamais du =EAtre faite et qui provoquait des plantages.
Le probl=E8me c'est que je ne sais pas comment emp=EAcher la copie de
l'objet sauf en passant par un pointeur.
Voici un exemple reproduisant mon probl=E8me :
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=3D=3D( B const& copy )
{
n_ =3D 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;
// =E9tape 1
a.add( "string 1" );
a.add( "string 2" );

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

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

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

Merci.

5 réponses

Avatar
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 '=').

Par ailleurs, le mot "copy" ici me paraît douteux. Un nom comme
"source" me semble plus adéquat.
Avatar
James Kanze
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
Avatar
philippe.lrx
On 30 mar, 08:46, Fabien LE LEZ wrote:
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.
Avatar
philippe.lrx
On 30 mar, 09:32, James Kanze wrote:
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.
Avatar
Mickaël Wolff
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