Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
5342 connectés 

 


Dernière réponse
Sujet : Passage par références en C++
Goooopil Je suis bien, d'accord avec vous tous mais vous oubliez un truc : les pointeurs, c bien quand c plus pratique qu'un passage par référence. Et encore faut pas oublier de libérer la mémoire

 


Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Goooopil Je suis bien, d'accord avec vous tous mais vous oubliez un truc : les pointeurs, c bien quand c plus pratique qu'un passage par référence. Et encore faut pas oublier de libérer la mémoire

 

darthguy Bien joué H4dd3R !!!
 
C'est clair, j'avais pas pensé à ça... C'est un peu tordu mais c'est clair qu'on peut le planter comme ça.
 
Tant pis, je retenterai ma chance la prochaine fois ! :D
 
PS : Je confirme BifaceMcLeOD. T'as tout à fait raison. La preuve ! ;)
H4dd3R Et ben non, DarthGuy, l´emploi de références ne permet pas du tout de securiser le code par rapport aux pointeurs!! je reprends ton exemple:
 
void foo2(A& a)ss
{ss
a.i = 0;ss
}

 
Et je fais:
 
void Main()
{
foo2(*(A*)0);
}

 
Et c pareil qu´avec des pointeurs, je peux passer une référence sur un object non instancié!! :(
BifaceMcLeOD Quand je dis que C++ n'est vraiment pas adapté à ceux qui apprennent à programmer... Vous réalisez le nombre de choses qu'il faut garder à l'esprit pour ne pas faire d'erreur de programmation ? :rolleyes:

 

H4dd3R Bien vu Verdoux!! Ouf mon compiler est pas si con!! ;)
Effectivement j´aurais du écrire ((m&)fille).fct(); et non pas ((m)fille).fct();..
C cool j´apprends bcp ds ce formum!! :) :) :)
verdoux Oui, mais là c'est normal !
Avec (m)fille tu crées un objet temporaire de type m sur lequel t'appelles la fonction fct.
H4dd3R Euhhh désolé Verdoux, mais alors mon VC++6 est VRAIMENT bizarre..
Parce que c une copie d´écran:
 
class m
{
public:
 virtual void fct();
};
 
void m::fct()
{
 int i=0;ss <= ici un breakpoint
}
 
class f: public m
{
public:
 void fct();
};
 
void f::fct()
{
 int i=1;
}
 
BOOL CTestReferencesApp::InitInstance()
{
 f fille;
 
 ((m)fille).fct();
 
 return FALSE;
}

 
Et je me tape le breakpoint!!!ss:(
 
Avec ((m*)&fille)->fct() non... Help!!
seblamb Verdoux -> Tu as raison en fait c'était dans un cas beaucoup plux complexe que ça ne marchait pas.
verdoux Euh non, le polymorphisme marche bien avec les références !
H4dd3R Aaaaargh!!! Tu as raison seblamb!! :(
Je veux plus entendre parler de références!! A part pour les copy constructors bien sûr.. ;)
Saloperie de C++!! Grrr vivement le Java.. :D
seblamb Malheureusement il y a une grosse limitation :ss
 on ne peut plus utlisiser de fonction virtuelles correctement !!!
 
class Ass
{
 virtual void f1();
};
 
class B : public A
{
 virutal void f1();
};
 
void ftest1{ A &a)
{
 a.f1();
}
 
void ftest2{ A *a)
{
 a->f1();
}
 
 
int main(void)
{
 B b;
 ftest1(b);
 ftest2(&b);
}
 
dans cet example "ftest1(b)" va excuter la fonction "f1" de la calsse A et et pas celle de la classe B. Alors que dans "ftest2(&b)" ça fonctionne correctement
H4dd3R DarthGuy merci!! J´y avais jamais pensé au coup de la sécurité sur l´espace mémoire alloué!! je sens que je vais plus jamais utiliser de pointeurs moi!! :D

 

darthguy Je rajouterai juste que les references sont aussi un moyen de securiser le code par rapport aux pointeurs.ss
 
Dans l'exemple de seblamb,ss
<table width="80%"><tbody><tr><td><font size="1" face="Arial, Verdana">Citation :</font><hr><font size="2" face="Arial, Verdana">void foo1(A *a)ss
{ss
a->i = 0;ss
}ss
 
void foo2(A& a)ss
{ss
a.i = 0;ss
}ss
</font><hr></td></tr></tbody></table>
 
Les deux fonctions font exactement la même chose. Cependant, pour celle dont le paramètre est un pointeur, rien ne t'assure que ce pointeur pointe bien sur un espace memoire alloué. Il peut être a null par exemple. Le compilateur ne criera jamais sur une erreur comme celle-la. Mais quand, à l'exécution, t'arrives à la ligness
a->i = 0;
Ben paf, ca plante. Avec les références, t'as pas ce type de bug.
 
 
 
Pour les fonctions renvoyant des réferences, je prends l'exemple de l'opérateur =. Le prototype type est celui la
 
NomClasse& operator=(const NomClasse&);
 
Dans cette fonction, le paramètre est une référence sur une autre instance de la classe que tu ne pourras pas modifier (const). Et pour cause, il est source de la copie, pas destination.ss
Pis la référence en retour (*this) sert quand tu veux faire plusieurs égalités en cascade par exemple.ss
 
Objet1 = Objet2 = Objet3;
 
Ici, on effectue Objet2 = Objet3, qui retourne une reference sur Objet2 (on va l'appeler RefObjet2).
Pis on effectue
Objet1 = RefObjet2.
 
De la même maniere, tu peux ecrire un truc du genre
Objet1::Fonction1(Objet2 = Objet3); par exemple.ss
On copie Obket3 dans Objet2 pis on passe la reference de Objet2 à la Fonction1.ss
Alors c'est pas tres propre, ca nuit a la lisibilite, mais ca passe.
 
J'ai repondu a ta question ?
BifaceMcLeOD Quand on apprend à programmer en C, on apprend vite que globalement, quand on veut modifier une donnée, il faut passer un pointeur dessus.
 
En C++, une référence, c'est un pointeur, ni plus ni moins. Sauf qu'on n'a jamais besoin de déréférencer le pointeur pour accéder à la donnée pointée (c'est-à-dire écrire *p ou p->..., un simple p ou p. ... suffit). C'est tout.
 
Après, l'utilité des pointeurs et des références, quand tu ne modifies pas tes données, c'est d'éviter des recopies inutiles de tes structures de données en appelant des fonctions. En passant un pointeur dessus, on recopie juste la valeur d'un pointeur sur ta structure de données, au lieu de recopier toute la structure de données. C'est moins coûteux. D'où l'utilité des const T* ou des const T&.
 
Enfin, certains prototypes d'opérateurs, genre operator=(), operator==() ou operator+(), sont standard, ils sont définis par le langage et tu ne dois pas les modifier. Donc si tu veux redéfinir l'opérateur d'affectation sur le type T, par exemple, tu devras écrire T& T:: operator(const T&), et pas un autre prototype, pas le choix.

 

heffer D'accord pour les arguments. Mais dans quels cas une fonction renvoie-t-elle une référence? Comme objet& f(...) par exemple.
Krueger seblamb > Arf, tu m'as devancé, mais nos posts sont complémentaires. ;)
Krueger Dans ton cas les références t'évites à passer les arguments par valeur qui nécessiterait une copie de l'objet en question. Et qui sait que les clases peuvent contenir beaucoup de membres et méthodes. :)
 
Un conseil: au lieu de passer tes objets par valeur passe les par référence constante si tu ne les modifies pas dans ta méthode. Ainsi tu as 'void f(const MyClass & myObject)' au lieu de 'void f(MyClass myObject)'.
Mais attention ça peut poser plein de problèmes de références constantes / non constantes si tu n'as pas bien défini tes classes.
seblamb Quand ont ne veut pas utliser les pointeurs.
En C++ quand ont veut affecter une valeur à un objet en le passant comme parametre à une fonction il faut donner un pointeur sur cette objet.ss
Avec le passage par reference on peut directerment donner l'objet.
 
class A
{
 public :
ssint i ;
};
 
void foo1(A *a)
{
 a->i = 0;
}
 
void foo2(A& a)
{
 a.i = 0;
}
 
int main(void)
{
 A aa;
 foo1(&a);
 foo2(a);
}
 
foo1 et foo2 font exactement la même chose;
heffer J'ai du mal à comprendre à quoi ça sert de renvoyer des valeurs par référence dans les fonctions d'une classe. Par exemple pour surdéfinir l'opérateur d'affectation.
Et quand doit-on passer les arguments par référence?

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)