OVH Cloud OVH Cloud

Classe non copiable et friend

22 réponses
Avatar
Fabien LE LEZ
Bonjour,

J'ai deux classes :
- une classe C, qui a un certain nombre de fonctions et
variables privées ;
- une classe F, qui doit légitimement avoir accès à la
quasi-totalité des éléments privés de C. Je la déclare donc amie :

class C
{
...
friend class F;
...
};

Jusque-là, rien d'exceptionnel -- c'est rare que j'utilise "friend",
mais dans mon cas ça se justifie.

Maintenant, je souhaite que C soit non-copiable. La méthode canonique
est de déclarer privés le constructeur de copie et l'opérateur =.
Seulement voilà, cette technique ne marche plus tout à fait, puisque F
a accès à ces fonctions privées.

Y a-t-il une solution élégante à ce problème, qui m'éviterait de
décréter qu'une classe non copiable n'a pas d'amies ?

Merci d'avance...



--
;-)

10 réponses

1 2 3
Avatar
Gabriel Dos Reis
Fabien LE LEZ writes:

| Bonjour,
|
| J'ai deux classes :
| - une classe C, qui a un certain nombre de fonctions et
| variables privées ;
| - une classe F, qui doit légitimement avoir accès à la
| quasi-totalité des éléments privés de C. Je la déclare donc amie :
|
| class C
| {
| ...
| friend class F;
| ...
| };
|
| Jusque-là, rien d'exceptionnel -- c'est rare que j'utilise "friend",
| mais dans mon cas ça se justifie.
|
| Maintenant, je souhaite que C soit non-copiable. La méthode canonique
| est de déclarer privés le constructeur de copie et l'opérateur =.
| Seulement voilà, cette technique ne marche plus tout à fait, puisque F
| a accès à ces fonctions privées.
|
| Y a-t-il une solution élégante à ce problème, qui m'éviterait de
| décréter qu'une classe non copiable n'a pas d'amies ?
|
| Merci d'avance...

Les aficiandos de Boost dérivent de boost::noncopyable
Avatar
Michel Michaud
Dans le message ,
Maintenant, je souhaite que C soit non-copiable. La méthode
canonique est de déclarer privés le constructeur de copie et
l'opérateur =. Seulement voilà, cette technique ne marche plus tout
à fait, puisque F a accès à ces fonctions privées.


En principe, on fait « moins » que les déclarer privés : on ne les
définit pas. Alors elle reste impossible à copier, même pour la
classe elle-même...

Y a-t-il une solution élégante à ce problème, qui m'éviterait de
décréter qu'une classe non copiable n'a pas d'amies ?


Il faut seulement dire qu'une classe non copiable, n'est copiable
par personne...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
kanze
Gabriel Dos Reis wrote:
Fabien LE LEZ writes:

| J'ai deux classes :
| - une classe C, qui a un certain nombre de fonctions et
| variables privées ;
| - une classe F, qui doit légitimement avoir accès à la
| quasi-totalité des éléments privés de C. Je la déclare donc
amie :


| class C
| {
| ...
| friend class F;
| ...
| };

| Jusque-là, rien d'exceptionnel -- c'est rare que j'utilise
"friend",

| mais dans mon cas ça se justifie.

| Maintenant, je souhaite que C soit non-copiable. La méthode
| canonique est de déclarer privés le constructeur de copie et
| l'opérateur =. Seulement voilà, cette technique ne marche plus
tout

| à fait, puisque F a accès à ces fonctions privées.

| Y a-t-il une solution élégante à ce problème, qui m'éviterait
de

| décréter qu'une classe non copiable n'a pas d'amies ?

Les aficiandos de Boost dérivent de boost::noncopyable


Devient-elle standard ?

Tout au départ (il y a environ 15 ans), j'avais ma classe,
UncopiableObject, pareil que boost::noncopyable, et je dérivais. En ce
qui me concernait, je trouvais que c'était bien plus lisible et
compréhensible : MaClasse estUn UncopiableObject -- quoi de plus clair
?

Mais comme dit Fabien, l'idiome canonique, c'est le constructeur et
l'opérateur privé. Et chaque fois qu'un autre se mettait à se servir
de
mes classes, il fallait qu'il apprennent mon idiome. Et il se posait la
question : pourquoi ? À quoi sert cette classe UncopiableObject ? Du
coup, j'y ai rénoncé, et je suis revenu à l'idiome du départ.

Maintenant, si boost::noncopyable devient standard, et qu'on peut
s'attendre à tout programmeur C++ le connaît, ça change tout.

--
James Kanze GABI Software http://www.gabi-soft.fr
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
Jean-Marc Bourguet
Fabien LE LEZ writes:

Maintenant, je souhaite que C soit non-copiable. La méthode
canonique est de déclarer privés le constructeur de copie et
l'opérateur =. Seulement voilà, cette technique ne marche plus tout
à fait, puisque F a accès à ces fonctions privées.


Pourquoi? Tu les as declares mais pas defini, donc tu devrais avoir
une erreur au link. C'est moins agreable qu'une erreur a l'endroit ou
tu tentes de copier mais c'est mieux que rien.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Gabriel Dos Reis
writes:

| > | Y a-t-il une solution élégante à ce problème, qui m'éviterait
| de
| > | décréter qu'une classe non copiable n'a pas d'amies ?
|
| > Les aficiandos de Boost dérivent de boost::noncopyable
|
| Devient-elle standard ?

Je ne sais pas. Mais je crois que c'est bien connu des aficianados de
Boost.

-- Gaby
Avatar
David Geldreich
Bonjour à tous,

Michel Michaud wrote:
En principe, on fait « moins » que les déclarer privés : on ne les
définit pas. Alors elle reste impossible à copier, même pour la
classe elle-même...


Faux, si tu ne définis pas de copy-constructor ou d'operator=, le
compilateur t'en fournit un par défaut donc l'objet est copiable par tout le monde.

Avatar
Jean-Marc Bourguet
David Geldreich writes:

Bonjour à tous,

Michel Michaud wrote:

En principe, on fait « moins » que les déclarer privés : on ne les
définit pas. Alors elle reste impossible à copier, même pour la
classe elle-même...


Faux, si tu ne définis pas de copy-constructor ou d'operator=, le
compilateur t'en fournit un par défaut donc l'objet est copiable par tout
le monde.


Michel dit que non seulement on les declare prive mais en plus on ne
les definit pas. Donc comme ils sont declares prives, il y a une
erreur quand l'exterieur essaie de les utiliser, comme ils sont
declares mais non defini, il n'y a pas de version fournie par le
compilateur et si ils sont utilises par la classe ou des friends, il y
a un probleme de link.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Dug
Fabien LE LEZ wrote in
news::

Bonjour,

J'ai deux classes :
- une classe C, qui a un certain nombre de fonctions et
variables privées ;
- une classe F, qui doit légitimement avoir accès à la
quasi-totalité des éléments privés de C. Je la déclare donc amie :

class C
{
...
friend class F;
...
};

Jusque-là, rien d'exceptionnel -- c'est rare que j'utilise "friend",
mais dans mon cas ça se justifie.

Maintenant, je souhaite que C soit non-copiable. La méthode canonique
est de déclarer privés le constructeur de copie et l'opérateur =.
Seulement voilà, cette technique ne marche plus tout à fait, puisque F
a accès à ces fonctions privées.

Y a-t-il une solution élégante à ce problème, qui m'éviterait de
décréter qu'une classe non copiable n'a pas d'amies ?

Merci d'avance...





Salut,

Pourquoi ne pas hériter C d'une classe copiable // , avec une fonction
virtuelle pure pour éviter de l'utiliser ?

class C_copiable
{

virtual void nepasutiliser() const = 0;
...
friend class F;
...
};

// C : non copiable
class C : public C_copiable
{
nepasutiliser() const {}; //
};

F a accès à toutes les variables et valeurs de C_copiable.
On ne peut pas instancier C_copiable, donc on peut pas faire des
copies de C_copiable.

Dans C, on peut définir les opérateurs de recopie et op= privés pour
empêcher la copie.

Ou je dis une bêtise? :)

Avatar
Fabien LE LEZ
On 21 Dec 2004 15:46:22 GMT, Dug :

On ne peut pas instancier C_copiable


Uh ? Mais je tiens à pouvoir l'instancier. Ce que je veux, c'est ne
pas pouvoir la copier.


--
;-)

Avatar
Christophe Lephay
"David Geldreich" a écrit dans le message
de news: cq9b45$7ev$
Bonjour à tous,

Michel Michaud wrote:
En principe, on fait « moins » que les déclarer privés : on ne les
définit pas. Alors elle reste impossible à copier, même pour la
classe elle-même...


Faux, si tu ne définis pas de copy-constructor ou d'operator=, le
compilateur t'en fournit un par défaut donc l'objet est copiable par tout
le monde.


Oui, c'est ce que voulait dire Michel. C'est pour ça qu'il a mit moins entre
guillemets. Le problème de sa formulation, c'est qu'il faut le connaitre lui
et connaitre la solution pour comprendre ce qu'il a voulu dire ;)

Chris


1 2 3