1

yop,


Bonne année à tous d'abord, pour ce premier topic de l'année happy

Bon, je me pose une question de C++, quelles sont les différences entre le fait d'écrire un constructeur avec un argument par défaut, ou deux , donc un sans argument et un autre redéfini avec un argument ?

Pour faire plus simple, ces deux classes sont-elles strictement équivalentes :class A { public: A (int x = 0); // Affecte x à A_x private: int A_x; } class B { public: B (); // Affecte 0 à B_x B (int x); // Affecte x à B_x private: int B_x; }
Si ces deux classes sont équivalentes dans la pratique, y a-t-il une méthode vraiment plus propre/flexible/whatever que l'autre ? Merci d'avance. smile

2

J'utiliserais plutôt la première version — avec argument par défaut.
En plus, en C++ il ne me semble pas qu'on puisse appeler un constructeur depuis un autre pour factoriser le code, donc voilà.

Pas sûr de tout ça, moins je fais de C++ mieux je me porte, je suis donc un peu rouillé...


nananée

3

Dans les langages qui acceptent les paramètres nommés comme le C#, la seconde forme est préférable à la première pour éviter les soucis de compatibilités.

Mais pour le C++, il me semble bien que deux formes sont vraiment équivalentes.
avatar

4

Comme discuté hier sur IRC, ces deux formes n'ont pas la même signification et ne génèrent pas le même code. En revanche pour compléter ./2, depuis C++11 on peut (enfin !) appeler on constructeur depuis un autre.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

5

Ah, OK ; intéressant, merci.

6

Oui, merci à tous. Et c'est intéressant cette nouveauté du C++11, mais juste au premier regard, je trouve ça étrange niveau propreté. Ca doit être pour racourcir encore les écritures. Au niveau factorisation du code, rien n'empêchait auparavant les constructeurs d'appeler une méthode privée.

7

Bah oui, mais c'est quand même dommage de ne pas pouvoir mettre 100% de ton code de construction dans un constructeur (et en plus d'être obligé d'avoir une méthode privée qui ne sert qu'une fois et qu'il ne faut surtout pas appeler en suite au risque de mettre l'objet dans un état incohérent).

Accessoirement, il ne faut jamais appeler une méthode virtuelle dans un constructeur, donc ça limite encore davantage les possibilités de ce hack ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

8

pencil

9

que c'est beau le c++, comme le java mais en moins bien </loin>

10

(et moche)

11

(et plus performant)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

12

(quand c'est bien écrit, ce qui est rarement le cas — et en plus, faut être réaliste : sauf domaine particulier, ça ne fait pas la moindre différence)

13

(et plus performant)

bof... pour ca rien ne vaut l'assembleur...
avatar
HURRRR !

14

(ça c'est vrai trilove)

15

(et c'est pas Folco qui dira le contraire happy)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

16

Pen^2 (./12) :
et en plus, faut être réaliste : sauf domaine particulier, ça ne fait pas la moindre différence)
(c'est bien pour ça que je code en c# trilove)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

17

hm sinon y a ptet un cas tres subtil foireux dans lequel ca change quelquechose niveau utilisation, mais comme ca je vois pas quoi, non. (mis a part ce que dit bob, mais ca c'est invisible niveau utilisation)

par contre, pour autre chose que les constructeurs, pour les fonctions membres, ca peut changer quelquechose.

tu peux demander explicitement le pointeur vers methode de la methode sans parametres, ou avec le parametre par defaut:
class A { public: A(); int Truc() const; int Truc(int x = 0) const; }; void Tralala() { (int (A::*)() const)&A::Truc; // va chercher Truc() (int (A::*)(int) const)&A::Truc; // va chercher Truc(int x = 0) }

(trioui)
avatar
HURRRR !

18

heu arg #vomi#, on peut déclarer les deux en même temps ? confus
C'est à peine dangereux et source de comportements étranges #tricouic#

19

bon en pratique si tu declare des variables du bon type, et que t'assigne &A::Truc dedans, ca va auto-choisir la bonne. mais le pbl se pose si t'utilise une fonction template, il faut que tu caste explicitement comme au dessus pour forcer le choix du type que tu veux... bref
avatar
HURRRR !

20

(cross)
bah ouai tu peux, c'est pas la meme signature grin
par contre tu peux pas utiliser les deux en meme temps sans parametres, ca fera comme le constructeur par defaut et le constructeur avec parametre avec valeur par defaut : le compilo sait pas lequel choisir tritop#triutile#
avatar
HURRRR !

21

la bonne ?
mais comment tu différencies entre
a.Truc() ;
et
a.Truc() ;
?
confus


edit : cross crossé ; on est d'accord grin

22

la bonne? bah cke je veux dire c'est que si t'assigne le pointeur dans des variables deja du bon type t'as pas besoin de cast explicite:
class A { public: A(); int Truc() const; int Truc(int x = 0) const; }; void Tralala() { int (A::*p0)() const = &A::Truc; // va chercher Truc() int (A::*p1)(int) const = &A::Truc; // va chercher Truc(int x = 0) }

grin

pis bon au pire pour les appeler sans parametres tu peux toujours faire:

((int (A::*)() const)&A::Truc)(); // appelle Truc()
((int (A::*)(int) const)&A::Truc)(); // appelle Truc(int x) avec x = 0
avatar
HURRRR !

23

tiens j'ai une idee a la con... trilove
avatar
HURRRR !

24

boooobs (./22) :
la bonne? bah cke je veux dire c'est que si t'assigne le pointeur dans des variables deja du bon type t'as pas besoin de cast explicite:
class A { public: A(); int Truc() const; int Truc(int x = 0) const; }; void Tralala() { int (A::*p0)() const = &A::Truc; // va chercher Truc() int (A::*p1)(int) const = &A::Truc; // va chercher Truc(int x = 0) }

grin
oué oué, j'avais crossé, je ne voyais pas bien le rapport entre ta réponse qui n'en était pas une et ma remarque qui en était une cheeky
pis bon au pire pour les appeler sans parametres tu peux toujours faire:

((int (A::*)() const)&A::Truc)(); // appelle Truc()
((int (A::*)(int) const)&A::Truc)(); // appelle Truc(int x) avec x = 0
Oué c'est sûr, mais bon grin



C'est quoi l'idée ? trilove

25

26

oui, c'est comme le java mais en moins bien </loin>

27

28

(et plus performant)

29

./24> non rien en fait... c'etait "comment perdre 15 minutes de sa vie pour un truc qui sert a rien" trioui
avatar
HURRRR !

30

grin