PETITE QUESTION : Objet, pointeur ou référence????

Signaler
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013
-
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013
-
Bonjour à tous,

j'ai une petite question, et si quelqu'un pouvait me répondre se serait sympa...

Donc en fait j'ai une classe contenant diverse choses, et notamment une méthode...
Dans cette méthode je fais appel à des différents objets de classe... donc ma question est la suivante, dans le corps d'une fonction est-il préférable de créer :
- un pointeur sur mon objet
(classeObjet objet* = new classeObjet(arg...);)
- une référence sur l'objet
(classeObjet &objet = classeObjet(arg,...);)
- ou tout bêtement l'objet directement
(classeObjet objet(arg,...);)

Merci d'avance

Peupeu

8 réponses

Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
113
L'objet lui même quelque soit l'endroit où tu es, sans hésitation.

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013

Ok, merci pour ta réponse....
Donc j'ai bien compris, quelque soit l'endroit où je suis...

Mais je vais être bête une dernière fois, si par hasard j'ai une classe dont l'un des arguments membres est un objet, on met aussi l'objet direct?
Je suis désolé de rebondir, car c'est typiquement ce que je fais, comme dans le bout de code ci-joint... du coup je redemande histoire de pas modifier tout mon code pour rien....

Par exemple, typiquement je fais un truc dans le genre :

class CObjet
{
public :

CObjet::CObjet(); // const de défaut
CObjet::CObjet(const CObjet &objet); // const de copie
CObjet::CObjet(const CAutreObjet &autreObjet) // constructeur
{
_autreObjet = new CAutreObjet(autreObjet);
};
CObjet::~Cobjet() {delete _autreObjet;}; // destructeur

private :
CAutreObjet* _autreObjet;
...
}

Merci d'avance
Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
113
Là, en revanche, pour un attribut de classe, ça dépend.

Si c'est un objet qui doit être dupliqué, alors tu mets l'objet. Ex: std::string.
class Objet
{
public :
Objet()
{
}

void setObject(const std::string& autreObjet)
{
  _autreObjet = autreObjet;
}
~Objet() {};

private :
 std::string _autreObjet;
}


Si c'est un objet dont tu dois juste avoir une référence dessus, donc pas de copie de celui-ci, alors tu mets un pointeur.
Si tu ne fais que pointer dessus, ce n'est pas à toi de détruire la chaîne.
class Objet
{
public :
Objet()
 : _autreObjet(0)
{
}

void setObject(const autreObjet& autreObjet)
{
  _autreObjet = autreObjet;
}
~Objet() {};

private :
 AutreObjet* _autreObjet;
}


Si c'est un objet essentiel à la construction de la classe, tu peux utiliser une référence:
class Objet
{
public :
Objet(const AutreObjet& autreObjet)
 : _autreObjet(autreObjet);
{
  
}
~Objet() {};

private :
 AutreObjet& _autreObjet;
}


Tu peux mettre un pointeur (et donc gérer la destruction de celui-ci), si tu ne peux faire autrement.
Ex: Construction d'une classe mise en attribut en dehors du constructeur.

class Objet
{
public :
Objet()
 : _autreObjet(0) // On l'initialise tout de même !
{
}

void setObject(int nb)
{
  delete _autreObjet;
  _autreObjet = new autreObjet(nb);
}

~Objet() { delete _autreObjet;};

private :
 AutreObjet* _autreObjet;
}



Ce n'est pas une règle d'or, et il y a sûrement des cas particuliers. Mais d'une manière générale, dès que tu peux éviter les pointeurs (et les new/delete) fait le !

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013

Super!!!
Merci pour ta réponse!!!
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
2
Salut,

je viens completer ces réponses de manière plus générique.
Les règles de base à suivre sont les suivantes :

1) Si un objet a pour vocation d'etre passé a une fonction, il faut le passer en pointeur si et seuleument cet objet fait plus de 4bytes, soit la taille d'un pointeur. La raison est simple. Si tu as un objet complexe dont la taille est supérieure à 4 bytes, tu vas de ce fait surcharger la pile pour rien et donc detériorer les performance de ton application.

typedef struct {
int age;
int taille;
} MYSTRUCT, *PMYSTRUCT;

sizeof(MYSTRUCT) => 8 bytes

PMYSTRUCT pMyObject;
sizeof(pMyObject) => 4 bytes

=> Tu comprends donc que tu as tout intéret a passer l'object par pointeur s'il est destiné a être utilisé en paramètre d'autres fonctions.

2) Que tu utilises des pointeurs ou des référence cela est "strictement identique". La seule différence entre les deux est que la référence est fixe une fois initialisée. A l'inverse un poiteur peut être déplacé!


Shell
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013

Ok, j'ai bien compris...
D'ailleurs ca me fait penser à une autre question....
A propos de la pile et du tas....

J'ai compris que lorsqu'on appelle une fonction, les arguments de celle ci sont copiés dans la pile, comme tu l'as souligné dans ton message...

Mais qu'en est-il du tas? dans quel cas il est utilisé?

peupeu
Messages postés
2671
Date d'inscription
vendredi 25 janvier 2002
Statut
Membre
Dernière intervention
6 février 2013
2
La pile (stack) correspond a de la mémoire paginée par "tranche" de 4ko qui sert aux allocation temporaires tel que le passage de pointeur, l'utilisation de variable locale non static a une fonction, ... La pile est donc "ephémère". La pile est accedé selon le principe de LIFO (last in first out).

A l'inverse le tas est alloué au démarrage du programme et sa taille est fixe si je ne me trompe pas. Il est utilisé pour l'allocation de zone mémoire via new, malloc, ...

Shell
Messages postés
57
Date d'inscription
mardi 11 mars 2003
Statut
Membre
Dernière intervention
24 avril 2013

Ok, merci pour ta réponse!!!