Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

heritage question (2)

7 réponses
Avatar
Bruno Causse
Je change de fils, (ai je tort?)

class A {
.../...
int score;
A* next
};

class B:public A {
.../...
};

../..

B tab_b[MAX_LIST];
B* list_b = &tab_b;


B* courant = list_b + 1;
A* previous = list_b;


//construction de la liste
for(...){
init_A(*courant); //prend un A en param

previous = previous->next = courant++;
}

previous->next = NULL;

../..

for(B* iter = list_b->next ; iter!=NULL; iter=iter->next)
init_B(*iter); //prend un B en Param

n'ayant pas de compilateur sous la main, mon code est il correct (dans la
construction de la liste)?

j'ai aussi une fonction de tri (sur score), je souhaite quel fonctionne pour
une liste de A mais aussi de B

list_b->sort_by_score();

void A::sort_by_score() {
A *best, *previousBest, *previous;
for(A* iter = this; iter->next != NULL; iter = iter->next){
previousBest = iter;
for(previous = previousBest->next; previous->next != NULL; previous
=previous->next)
if(previousBest->next->score>previous->next->score)
previousBest = previous;
if(previousBest != iter) {
best = previousBest->next;
previousBest->next = best->next;
best->next = iter->next;
iter->next = best;
}
}
}

est ce valable?

7 réponses

Avatar
Fabien LE LEZ
On Mon, 27 Aug 2007 14:36:21 +0200, "Bruno Causse"
:

n'ayant pas de compilateur sous la main, mon code est il correct


Si tu as accès à Internet, tu as un compilateur sous la main :
http://www.comeaucomputing.com/tryitout/

Avatar
Fabien LE LEZ
On Mon, 27 Aug 2007 14:36:21 +0200, "Bruno Causse" :

est ce valable?


As-tu une bonne raison de ne pas utiliser std::list et std::sort ?

Avatar
Michael DOUBEZ
Je change de fils, (ai je tort?)


Je suis sûr que le mien n'apprécierait pas.

[snip]


//construction de la liste
for(...){
init_A(*courant); //prend un A en param


Tu veux dire prends un A& en param ?


previous = previous->next = courant++;
}

previous->next = NULL;

../..


Ca me parait bien compliqué pour initialiser une liste surtout dans un
tableau.

Par exemple:

for(int i=0;i<MAX_LIST;++i)
{
//initialize A part
init_A(tab_b[i]);
//Chain list
tab_b[i].next=&(tab_b[i+1]);
}
//next of last element is NULL
tab_b[MAX_LIST-1].next=NULL;


for(B* iter = list_b->next ; iter!=NULL; iter=iter->next)
init_B(*iter); //prend un B en Param


->next est un A* donc il te manque un dynamic_cast<B*>().


n'ayant pas de compilateur sous la main, mon code est il correct (dans la
construction de la liste)?

j'ai aussi une fonction de tri (sur score), je souhaite quel fonctionne pour
une liste de A mais aussi de B [snip]


Franchement, tu gagnerais beaucoup de temps et tu aurais un code plus
robuste avec un std::list<>.

Michael

Avatar
Bruno Causse
"Michael DOUBEZ" a écrit dans le message de news:
46d3d6a0$0$19594$
Je change de fils, (ai je tort?)


Je suis sûr que le mien n'apprécierait pas.



MDR, ca doit etre subconscient ;-)

->next est un A* donc il te manque un dynamic_cast<B*>().


oui, je l'ai compri, c'est une difference par rapport a java (du moins dans
l'criture du code)


Avatar
Bruno Causse
"Michael DOUBEZ" a écrit dans le message de news:
46d3d6a0$0$19594$

Franchement, tu gagnerais beaucoup de temps et tu aurais un code plus
robuste avec un std::list<>.


oui pourquoi pas (si les perf sont les memes, rappel : le nombre de
creation/suppression de listes)

pour l'instant j'en suis

class A {
.../...
//plus de pointeur next
}

class B : public A {
.../...
}

template <class T>
class Movelist {
T move;
T* next;

.../...
}

Avatar
Michael DOUBEZ
"Michael DOUBEZ" a écrit dans le message de news:
46d3d6a0$0$19594$
Franchement, tu gagnerais beaucoup de temps et tu aurais un code plus
robuste avec un std::list<>.


oui pourquoi pas (si les perf sont les memes, rappel : le nombre de
creation/suppression de listes)


Si les perfs sont une préoccupation, tu devrais peut être éviter les
dynamic_cast<> dans les boucles. Tu n'as pas à priori d'héritages
multiples ou autres bizarreries donc il devrait être assez rapide mais
ça rajoute quand même des checks évitables et à l'impact difficilement
quantifiable.


pour l'instant j'en suis

class A {
.../...
//plus de pointeur next
}

class B : public A {
.../...
}

template <class T>
class Movelist {
T move;
T* next;

.../...
}


Je ne connais pas ton application donc je peux difficilement t'aider.
Mais:
* Typiquement, une MoveList (aux echecs je présume) sera plus
naturellement représentée par une pile. En l'occurrence un vector<>
plutot que stack<> pour avoir un vrai container.
* J'ai vu que tu avait des fonction init_A, init_B. Ca me laisse
penser que la relation d'héritage n'est pas nécessaire mais un
composition sera peut être plus adaptée et ton code plus maintenable.


Donc, ce serait quelque chose de l'ordre de :
class A {
//...
};

class B {
public:
A a;
//...
};

template <class T>
typedef std::vector<T> Movelist;


Michael


Avatar
Bruno Causse
"Michael DOUBEZ" a écrit dans le message de news:
46d4007f$0$424$

* J'ai vu que tu avait des fonction init_A, init_B. Ca me laisse penser
que la relation d'héritage n'est pas nécessaire mais un composition sera
peut être plus adaptée et ton code plus maintenable.


oui, c'etait ma premier idee, je n'ai surement pas assez developpée.