OVH Cloud OVH Cloud

Supprimer "private"

54 réponses
Avatar
Fabien LE LEZ
Bonjour,

Soit une classe, avec un certain nombre de membres privés ou protégés,
dans un programme donné, terminé, qui fonctionne.

À cause d'un "friend" illégal[*], que gcc n'accepte pas, je souhaite
supprimer la ligne "friend XXX" et les "private:" et "protected:"[**].

Il me semble que cette modification ne changera pas le fonctionnement
du programme.

Quelqu'un pourrait-il confirmer ?

Merci d'avance.




[*] <http://www.comeaucomputing.com/techtalk/templates/#friendclassT>

[**] Oui, je sais, ce n'est pas forcément une idée géniale, mais comme
je ne compte pas pondre du code qui utilise directement ces classes,
je ne pense pas avoir besoin de la protection apportée par "private"
et "protected".

10 réponses

1 2 3 4 5
Avatar
kanze
Laurent Deniau wrote:
kanze wrote:

Mais je me démande si tu ne faisais pas référence au
dynamic_cast -- un dynamic_cast respecte, en effet, les
private, et il se fait à l'exécution. Moi, je sais qu'en
fait, il


C'est a ca que je faisais reference et c'etait pour indiquer
que dans le cas de l'heritage, le comportement d'un programme
peut changer si on enleve/ajoute private.


C'est en effet vrai : si je fais un dynamic_cast< Derived* > sur
un Base* (qui désigne en fait un Derived), j'en recupère NULL si
l'héritage est privé, mais un pointeur non-nul si l'héritage est
public.

Je ne sais pas si l'effet est observable dans le code réel,
parce que si l'héritage est privé, je n'ai normalement aucun
moyen d'obtenir un Base* à partir d'un Derived*. (Mais une
fonction de Base, appelée depuis le Derived, a pû sauver son
adresse quelque part.)

C'est de toute façon un effet auquel je n'avais pas pensé.

--
James Kanze GABI Software
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
Gabriel Dos Reis
"kanze" writes:

| Je ne sais pas si l'effet est observable dans le code réel,

Nous avions par le passé eu des bug reports (un peu compliqués, mais
cela se résumait essentiellement à ça) donc, je crois que quelqu'un
est tombé dessus en pratique.

-- Gaby
Avatar
Marc Boyer
Bertrand Lenoir-Welter a écrit :
Mais si ton projet est conséquent ( même si tu es seul à bosser dessus ),
tu as tout intérêt à encapsuler correctement ton code, et là, la
notion de publique/private est très importante.


Je suis d'accord sans l'être. A mon avis, seule la lisibilité change
quand on bosse seul ou en équipe, et là ça devient moins lié à
l'utilisation de parties publiques ou privées/protégées que de
structuration générale. Un commentaire de 3 mots au bon endroit fait
beaucoup plus qu'une encapsulation orthodoxe.


La nuance (de taille), c'est que le compilateur n'oublie jamais
de lire le 'private', alors que le programmeur si.

Mais la question portait sur l'exécution même du code, il me semble. Je
ne pense pas que l'assembleur généré diffère pour une fonction publique
ou privée/protégée.


Je crois que tu as raté une partie du problème: si j'ai 2 fonctions
f(int) et f(double) dont l'une des deux est privée, et que j'appelle
f(1), qui appellera-t-il ?

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Marc Boyer
Le 14-09-2005, Fabien LE LEZ a écrit :
Bonjour,

Soit une classe, avec un certain nombre de membres privés ou protégés,
dans un programme donné, terminé, qui fonctionne.

À cause d'un "friend" illégal[*], que gcc n'accepte pas, je souhaite
supprimer la ligne "friend XXX" et les "private:" et "protected:"[**].

Il me semble que cette modification ne changera pas le fonctionnement
du programme.


Je suis quasiment sur d'avoir lu une remarque dans TC++PL où BS
écrit que les résolutions de surcharge ne dépendent pas de
private/public pour justement que ce soit toujours la même
fonction appellée quelque soit les règles de protection.
Donc, on peut espérer que cette règle soit partout
respectée, mais bon...
En plus, je retrouve pas le passage...

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?

Avatar
Bertrand Lenoir-Welter
Marc Boyer :

La nuance (de taille), c'est que le compilateur n'oublie jamais
de lire le 'private', alors que le programmeur si.


C'est bien ce que je disais : private n'a rien d'obligatoire pour une
programmeur qui n'a pas passé la nuit en boîte et a déjà bu son café.


Je crois que tu as raté une partie du problème: si j'ai 2 fonctions
f(int) et f(double) dont l'une des deux est privée, et que j'appelle
f(1), qui appellera-t-il ?


Vous codez souvent deux fonctions de même label dont une est privée et
l'autre publique ? Même après le café ? Même avec du sucre ? Dans
l'affirmative, je concède et vous avez raison. En précisant que, pour ma
part, ça risque pas de m'arriver.

Avatar
Gabriel Dos Reis
Bertrand Lenoir-Welter writes:

[...]

| > Je crois que tu as raté une partie du problème: si j'ai 2 fonctions
| > f(int) et f(double) dont l'une des deux est privée, et que j'appelle
| > f(1), qui appellera-t-il ?
|
| Vous codez souvent deux fonctions de même label dont une est privée et
| l'autre publique ? Même après le café ? Même avec du sucre ?

Oui.

struct stream {
stream();
explicit stream(const string&);
// ...

private:
stream(const stream&); // not implemented
// ...
};


| Dans l'affirmative, je concède et vous avez raison. En précisant que, pour
| ma part, ça risque pas de m'arriver.

de coder ?

-- Gaby
Avatar
Marc Boyer
Bertrand Lenoir-Welter a écrit :
Marc Boyer :

La nuance (de taille), c'est que le compilateur n'oublie jamais
de lire le 'private', alors que le programmeur si.


C'est bien ce que je disais : private n'a rien d'obligatoire pour une
programmeur qui n'a pas passé la nuit en boîte et a déjà bu son café.


Tu ne fais des erreurs d'inattention qu'après des nuits en boites
sans café après ? Heureux homme.
Moi, non.

Je crois que tu as raté une partie du problème: si j'ai 2 fonctions
f(int) et f(double) dont l'une des deux est privée, et que j'appelle
f(1), qui appellera-t-il ?


Vous codez souvent deux fonctions de même label dont une est privée et
l'autre publique ? Même après le café ? Même avec du sucre ? Dans
l'affirmative, je concède et vous avez raison. En précisant que, pour ma
part, ça risque pas de m'arriver.


Pour ma part non. Après, l'OP demandais si c'était garantit
*toujours*. Comme je ne connais pas son code...

Ensuite, c'est rare d'avoir deux fonctions f équivalentes,
mais avoir des opérateurs courants (<<, +, ->), c'est plus
que fréquent.

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Gabriel Dos Reis
Marc Boyer writes:

| Le 14-09-2005, Fabien LE LEZ a écrit :
| > Bonjour,
| >
| > Soit une classe, avec un certain nombre de membres privés ou protégés,
| > dans un programme donné, terminé, qui fonctionne.
| >
| > À cause d'un "friend" illégal[*], que gcc n'accepte pas, je souhaite
| > supprimer la ligne "friend XXX" et les "private:" et "protected:"[**].
| >
| > Il me semble que cette modification ne changera pas le fonctionnement
| > du programme.
|
| Je suis quasiment sur d'avoir lu une remarque dans TC++PL où BS
| écrit que les résolutions de surcharge ne dépendent pas de
| private/public pour justement que ce soit toujours la même
| fonction appellée quelque soit les règles de protection.

Exact. Cela a été une décision conscieuse de conception. Hélas, une
décision qui donne lieu souvent à débat depuis des temps immémoriaux,
surtout avec la floraison de langages dits « orientés objet » font un
design autre.

| Donc, on peut espérer que cette règle soit partout
| respectée, mais bon...
| En plus, je retrouve pas le passage...

Je n'ai pas mon TC++PL à côté (il n'est que 5h du mat), mais à défaut,
tu peux lire la norme

3.4/1
[...] Overload resolution (13.3) takes place after name lookup has
succeeded. The access rules (clause 11) are considered only once
name lookup and function overload resolution (if applicable) have
succeeded. Only after name lookup, function overload resolution
(if applicable) and access checking have succeeded are the
attributes introduced by the names declaration used further in
expression processing (clause 5).

-- Gaby
Avatar
Bertrand Lenoir-Welter
Marc Boyer :

Tu ne fais des erreurs d'inattention qu'après des nuits en boites
sans café après ? Heureux homme.


Oui mais, comme je suis modeste en plus d'être intelligent, je me dois
de préciser que je triche : tenez-vous bien, je n'appelle JAMAIS une
fonction "f" tout court. Ca vous épate, hein ?

Plus sérieusement, on a pas mal caricaturé ce que j'ai dit dans ce
thread - pardon ce troll. Si l'argumentaire consiste à trouver des
exemples bien tordus qui n'arrivent jamais en pratique ou dont on peut
se passer facilement et avec avantage, ou encore des cas d'écriture de
code qui vaudraient illico à leur auteur un avertissement avec mise à
pied, je concède tout en bloc et vous avez raison. Je n'ai jamais dit
qu'un private ne servait à rien dans le C++, mais seulement que je ne
m'en servais pas en projet solo et pourquoi, ensuite que ça modifiait
pas l'exécution ni la taille d'une classe. Si, a contrario, nous sommes
entre gens d'expérience qui avons acquis quelques bonnes - ou mauvaises
- habitudes au cours d'années de pratique, je vous prie de concéder que
mon style d'écriture, s'il n'est pas dans le Dogme, ne me vaudra pas les
Assises pour autant, mais tout juste les gros yeux, et encore.

Avatar
Fabien LE LEZ
On Mon, 19 Sep 2005 11:50:10 +0200, Bertrand Lenoir-Welter
:

Vous codez souvent deux fonctions de même label dont une est privée et
l'autre publique ?


Ça pourrait très bien m'arriver.

Ce matin, j'ai codé une structure du style :

namespace Machin {

class A { ... };

class B
{
class C { ... };
virtual void f (C const&)= 0;
};

}// end namespace Machin

class D: public Machin::B
{
virtual void f (C const&);
};


Sauf que j'avais, par erreur, donné le même nom à A et C. Du coup, je
me retrouvais avec plein de messages rigolos, qui variaient suivant
que je rajoute des "Machin::" ici ou là. J'ai mis un petit moment
avant de trouver le problème.

Donc, je ne sais pas pour toi, mais moi j'ai besoin de toute l'aide
qu'un compilo peut m'apporter. En d'autres termes, je déclare
systématiquement tout membre comme privé, sauf si j'ai une bonne
raison de le déclarer public.

1 2 3 4 5