1

Et oui, je commence tout juste en C++, alors j'ai une question de nioob :
j'ai une classe platform et une classe scheduler et j'aimerai créer d'abord une instance de platform puis la donner en argument à scheduler (histoire de créer plusieurs scheduler qui bossent sur la même instance de platform)
class scheduler
{
        public:
                scheduler(platform & );
                ~scheduler();
        private:
                platform p;
};
class platform
{
        public:
        private:
};


et dans mon code j'ai
scheduler::scheduler(platform & arg)
{
        p = arg;
}

int main(void) {
        platform essai;
        scheduler sched = scheduler(essai);
}

malheuresement, deux platform sont créées et à la fin, j'ai plein d'erreurs de malloc libérés deux fois :/
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

2

en fait je pense avoir trouvé, faut mettre des pointeurs (je pensais que par défaut c'était implicite)
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

3

Quand tu écris:
scheduler sched = scheduler(essai)

deux schedulers sont créés... et puis tu n'as apparement pas d'opérateur de copie pour les objets schedulers.
Un truc qui marchera avec ton code:

class scheduler {
        public: 
                scheduler(const platform & ); 
                ~scheduler(); 
        private: 
                platform& p; 
}

scheduler::scheduler(const platforme& _platform)
  : p(_platform)
{}

---------------------------

int main() 
{
        platform p;
        scheduler schedule1(p);
        scheduler schedule2(p);
}


Au lieu de passer par un pointeur comme tu le pensais, tu peux passer par une référence (ca permet de s'assurer que l'objet existe toujours notamment)

4

en fait, maintenant je fais
        platform* essai = new platform();
        scheduler* sched = new scheduler(essai);
        sched->run();

mais je vais me renseigner un peu sur les références (pour voir comment ça marche exactement ^^)
merci de ta réponse smile
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

5

ouais, enfin, pkoi passer par des pointeurs alors que tu peux passer par des références wink

6

les references franchement moi je n en vois pas l interet, je prefere les pointeurs.

7

bah c'est simple et clair d'utilisation (pas a se faire chier avec les allocs etc.)

8

nEUrOO :
ouais, enfin, pkoi passer par des pointeurs alors que tu peux passer par des références wink

parce que je ne sais pas ce que c'est ? cheeky
j'ai commencé le C++ en fin d'après-midi hier, alors je maîtrise pas tous les concepts hehe je vais regarder un peu la suite du tutorial que je suis ^^
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

9

JackosKing :
les references franchement moi je n en vois pas l interet, je prefere les pointeurs.

Les références permettent de se concentrer sur le fond et non sur la forme.

Passer des objets en paramètres sans avoir à réfléchir s'il doit être copié, si tu dois passer une adresse, ... tu passes ton objet et puis c'est tout.

C'est également plus modulaire, puisqu'en utilisant des références, l'implémentation peut passer d'un passage par référence à un passage par copie sans avoir à modifier les programmes appelant.

10

nEUrOO> si un constructeur par recopie ou un opérateur= standard n'est pas fourni, le compilateur se charge d'en fournir un par défaut, qui est une copie bit à bit. Pour cet exemple ce n'est pas genant.

J'aimerais revenir sur l'exemple de nEUrOO, qui est bon s'il fait ce que tu voulais...mais il faut savoir exactement ce que tu voulais =>

class platform {}; 

class scheduler 
{ 
        platform m_p;
public: 
        scheduler(platform & p) : m_p(p) {}
        ~scheduler(); 
};
class platform {}; 

class scheduler 
{ 
        platform m_p;
public: 
        scheduler(platform & p)  {m_p=p;}
        ~scheduler(); 
};
class platform {}; 

class scheduler 
{ 
        platform & m_p;
public: 
        scheduler(platform & p) : m_p(p) {}
        ~scheduler(); 
};


Ces trois exemples font des choses assez proches mais néanmoins différentes :
1) Le premier exemple a un membre de type platforme, qui est initialisé à partir du paramètre p. Si la classe platform disposait d'un constructeur par recopie, il serait appelé (ici le compilateur appelera le constructeur par défaut, qui fait une copie bit à bit).

2) Le deuxième exemple commence par créer un membre de type plateforme, initialisé avec son constructeur par défaut (s'il n'est pas fourni, comme dans cet exemple, le compilateur fournit un constructeur vide). Puis le corps du constructeur de scheduler assigne le paramètre au membre, au moyen de l'operator= (qui, ici est une copie bit à bit fournie par le compilateur).

3) Dans le dernier exemple (celui de nEUrOO), la classe scheduler ne contient pas de membre de type plateforme, mais une simple référence. Cette référence sera un alias pour l'objet passé en paramètre à la construction du scheduler (c'est à dire que &m_p == &p). Attention en particulier si l'objet en question est détruit avant le scheduler : la référence deviendra invalide.

11

Justement il vaut mieux savoir ce que l on fait, vive les pointeurs!

12

...

mieux vaut savoir ce que l'on fait, vive la programmation à l'éditeur hexa.

si tu connais le c++, tu sais ce que tu fais en utilisant les références hein.
nan parce que sinon, mieux vaut ne pas utiliser les opérateurs. Ni les classes d'ailleurs, des fois y'a des constructeurs dedans, tu sais pas ce qu'ils font de l'endroit où tu les appelles.

13

Ma reponse etait en particulier due a cette phrase:
"Passer des objets en paramètres sans avoir à réfléchir s'il doit être copié, si tu dois passer une adresse, ... tu passes ton objet et puis c'est tout."

Perso pour moi les references ne sont pas bonne evolution.

14

Dans ce cas le développement modulaire n'est pas pour toi.
Le détail du passage de paramètres relève de l'implémentation de la fonction. Ce n'est pas au programme appelant de s'en occuper.

15

Oui et non:
C'est également plus modulaire, puisqu'en utilisant des références, l'implémentation peut passer d'un passage par référence à un passage par copie sans avoir à modifier les programmes appelant.
-> avec les pointeurs c est bien pareil hein... si c'est juste changer une écriture par une autre, les references apportent rien de plus.

16

Marrant, je suis tombé recement sur un tel "troll" : "Utiliser le passage par référence ou le passage par Addresse ?"

Globalement c'est exactement la meme chose. Mais ce que j'en avais tiré du par référence (c'est ce que tu utilise d'ailleurs flanker en #0, le void gnagna:gnagna(class &objet), objet est passé par référence) c'est que ça peut poser des problèmes pour celui qui programme et utilise la classe (je parle justement de personnes qui ne programment pas forcement de maniere tres propre), le passage par addresse (classe *objet) force le programmeur a faire attention a ce que l'objet appelé *PEUT* modifier l'objet en parametre

(edit: pavé pas très digeste, je l'accorde, et au passage je #crayonne# bob sur le second paragraphe)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

17

C'est un bon compromis quand même, ça permet d'éviter un passage par copie tout en ayant beaucoup plus de sécurité qu'avec des pointeurs... je commence le C++ aussi, mais perso j'aurais tendance à passer par adresse dès que c'est possible.

Sinon un petit conseil de mon prof de C++ : par défaut, le constructeur par copie et l'operateur "=" vont faire une copie bit à bit, comme a dit Spectras, et quand tu as une classe qui contient des pointeurs ça peut faire n'importe quoi si tu avais l'impression de créer un nouvel objet autonome. Tu peux alors déclarer le constructeur par copie (TaClass (const TaClass& )) et l'operateur d'affectation (TaClass& operator= (const TaClass& )), sans les implémenter : si tu écris du code qui en a besoin, ça provoquera une erreur en t'obligeant à vérifier ce que tu fais plutot que de risquer une copie implicite potentiellement dangereuse.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

18

Zephyr
: je commence le C++ aussi, mais perso j'aurais tendance à passer par adresse dès que c'est possible.

Ben c'est toujours possible confus

Sinon moi je préfère les références du Java comme je l'ai déjà dit maintes fois sur ce forum, malheureusement le C++ n'est pas toujours très pratique avec les références sad
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

19

dès que c'est possible par rapport au programme que t'es en train de faire, patate ^^
si tu as besoin que ton attribut puisse temporairement n'être lié à aucun objet, les réferences c'est foutu par exemple
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

20

Donc "J'aurais tendance à utiliser les pointeurs dès que ce n'est pas possible d'utiliser les références" ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

21

désolé de squatter mon propre topic, mais est-ce que vous sauriez pourquoi cette fichue fonction me fait un bus error ? cheeky
int compare_double(const void* x, const void* y){
        double *xp, *yp;
        xp  = (double*) xp;
        yp = (double*) yp;
      if(*xp < *yp) return 1;//si on commente cette ligne, y a plus d'erreur, au passage ^^
        return 0;
}
›

        double* tAll;
        tAll = (double*) malloc(sizeof(double) * 2*p->n());
        for(i = 0; i < p->n(); i++) {
                tAll[2*i] = p->requests[i].r();
                tAll[2*i+1] = p->requests[i].d();
        }
        qsort(tAll, sizeof(double), 2*p->n(), &compare_double);
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

22

Flanker :
désolé de squatter mon propre topic, mais est-ce que vous sauriez pourquoi cette fichue fonction me fait un bus error ? cheeky
int compare_double(const void* x, const void* y){
        double *xp, *yp;
        xp  = (double*) xp;
        yp = (double*) yp;
      if(*xp < *yp) return 1;//si on commente cette ligne, y a plus d'erreur, au passage ^^
        return 0;
}
›

Heu je prend ça sur le compte de la fatigue ??

xp = (double*)xp
yp = (double*)yp

???
tu voulais pas plutot ecrire

xp = (double *)x;
yp = (double *)y;

?

Non parceque ton code la ne fait rien de bon sorry
Donc vu que xp, et yp pointe sur rien du tout de bon (apriori valeurs aléatoires donc n'importe ou en mémoire qui n'appartiens pas au programme) ton test fait tout foirer, vu que tu lit les valeurs de *xp et *yp
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

23

fatigue, non, mal de tête, sûrement grin

effectivement, je comprends mieux pourquoi ça ne marche pas cheeky
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

24

Sasume
: Donc "J'aurais tendance à utiliser les pointeurs dès que ce n'est pas possible d'utiliser les références" ?

Ah ok c'était ça la question... alors oui c'est ce que je voulais dire ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

25

C est ce qu il faut se dire, les reférences n apportent rien de plus au C++, je dirai meme plus que cela peut etre source d erreur.

26

Je serais curieux de savoir comment ? (un des objectifs étant précisément l'inverse, ça serait dommage grin)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

27

Sachant que tu ne sais pas si tu passes par copie ou par pointeur (a la lecture du code, si tu ne vois pas le prototype de la fonction), comment peux tu etre sur de l effet voulu?
C est justement ce qui est ridicule!
En gros je m exprimerai mieux en citant:
"Passer des objets en paramètres sans avoir à réfléchir s'il doit être copié, si tu dois passer une adresse, ... tu passes ton objet et puis c'est tout."
Personellement cela me fait sursauter quand je lis cela.

28

Heu le problème de C++ vient du fait qu'on le connait pas assez bien.
Les références ne posent aucun problèmes mais ont des limites, c'est tout... quand aux pointeurs en C++, ils ont uniquement été conservés parceque C++ devait intégrer C.

29

JackosKing
: Sachant que tu ne sais pas si tu passes par copie ou par pointeur (a la lecture du code, si tu ne vois pas le prototype de la fonction), comment peux tu etre sur de l effet voulu?

C'est à dire ? Déjà le prototype de la fonction, si tu veux l'appeler, t'es un peu obligé de le connaitre grin
Et puis si tu parles du fait qu'un passage par réference peut modifier l'objet que tu as passé en paramètre, alors si c'était uniquement pour gagner le temps de la copie et que ton objet n'est effectivement pas modifié, le mec qui a implémenté la routine se *devait* de mettre "const" dans le prototype. Le problème c'est que les gens ne savent pas coder en C++, pas qu'il est mal foutu...

[edit] Ah j'ai peut-être compris différement ce que tu voulais dire, en gros que quand on lit du code et qu'on voit "objet1.methode (objet2)", objet2 peut être passé par réference et donc être modifié sans que ça soit visible d'ici ? Oui effectivement, mais personne n'a dit qu'objet2 n'allait pas être modifié non plus, ça s'appelle les paramètres globaux et c'est légerement plus répendu que dans le petit monde du C++ happy
Et puis en suivant la même logique, quand on passe &objet en C, ça voudrait dire qu'il est forcément modifié ? Non, ça peut être aussi simplement pour gagner du temps... La seule chose qui te permet de savoir si la méthode modifie ou non l'objet passé en paramètre c'est son prototype, et son nom qui est supposé être explicite smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

30

nEUrOO :
Les références ne posent aucun problèmes mais ont des limites, c'est tout... quand aux pointeurs en C++, ils ont uniquement été conservés parceque C++ devait intégrer C.

Euh, tes deux phrases sont pas un peu contradictoires là ? trifus
Et la deuxième est nettement exagérée : les références ne sont, justement, pas modifiables, du coup elles ne conviennent pas dans un paquet de situations (par exemple tu ne peux pas les mettre dans un std::vector ^^). Evidemment, ça aurait pu être fait via une classe de la STL plutôt qu'avec un type built-in, mais ça n'aurait pas changé grand-chose smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)