C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

virtual

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Stephane Wirtel
Guest





PostPosted: Fri Apr 15, 2005 11:32 am    Post subject: virtual Reply with quote



Voici un problème qui m'ennuie à cause de l'héritage et du polymorphisme.

J'ai créé la classe abstraite Object avec les méthodes init et destroy
comme étant virtuelle pure.

Je crée la class NewObject à partir d'Object et j'implémente donc init et destroy
afin de pouvoir instancier un objet de la classe NewObject.

normalement, "this" représente l'objet dynamique, donc, normalement this->init () se trouvant
dans Object devrait faire appel à NewObject::init et non à Object::init.

Est-ce que je me trompe ?

#include <iostream>
#include <exception>

using namespace std;

class Object {
private:
public:
virtual void init (void) throw (exception) = 0;
virtual void destroy (void) = 0;
Object (void) {
cout << "Object::Object" << endl;
this->init ();
}
~Object (void) {
this->destroy ();
cout << "Object::~Object" << endl;
}
};

class NewObject : public Object {
private:
public:
NewObject () {
cout << "NewObject::NewObject" << endl;
}
~NewObject (void) {
cout << "NewObject::~NewObject" << endl;
}
void init (void) throw (exception) {
cout << "NewObject::init" << endl;
}
void destroy (void) {
cout << "NewObject::destroy" << endl;
}
};

int main (int argc, char **argv) {
NewObject obj;
return 0;
}
Back to top
Vincent Lascaux
Guest





PostPosted: Fri Apr 15, 2005 11:39 am    Post subject: Re: virtual Reply with quote



Quote:
Object (void) {
cout << "Object::Object" << endl;
this->init ();
}

Ici on est en train de construire Object
NewObject n'est pas encore initialisé
Ca n'a pas de sens d'appeler une fonction de NewObject (init).

J'imagine que le contexte est plus complexe, mais pourquoi ne pas mettre le
code d'init dans le constructeur de NewObject et celui de destroy dans son
destructeur ?

--
Vincent



Back to top
Stephane Wirtel
Guest





PostPosted: Fri Apr 15, 2005 11:40 am    Post subject: Re: virtual Reply with quote



Vincent Lascaux a écrit :
Quote:
Object (void) {
cout << "Object::Object" << endl;
this->init ();
}


Ici on est en train de construire Object
NewObject n'est pas encore initialisé
Ca n'a pas de sens d'appeler une fonction de NewObject (init).

J'imagine que le contexte est plus complexe, mais pourquoi ne pas mettre le
code d'init dans le constructeur de NewObject et celui de destroy dans son
destructeur ?

Parce que j'essaie de surcharger new, new[], delete, delete[] via un malloc & free, afin d'essayer de créer un memory manager
et qu'à ce moment là, le new n'appellera plus le constructeur de la classe que j'instancie.

Voilà pourquoi un init et un destroy.

Back to top
Horst Kraemer
Guest





PostPosted: Fri Apr 15, 2005 4:03 pm    Post subject: Re: virtual Reply with quote

On Fri, 15 Apr 2005 13:32:58 +0200, Stephane Wirtel
<stephane.wirtel (AT) descasoft (DOT) com> wrote:

Quote:
Voici un problème qui m'ennuie à cause de l'héritage et du polymorphisme.

J'ai créé la classe abstraite Object avec les méthodes init et destroy
comme étant virtuelle pure.

Je crée la class NewObject à partir d'Object et j'implémente donc init et destroy
afin de pouvoir instancier un objet de la classe NewObject.

normalement, "this" représente l'objet dynamique, donc, normalement this->init () se trouvant
dans Object devrait faire appel à NewObject::init et non à Object::init.

Est-ce que je me trompe ?

Normalement - à l'exceptions de constructeurs et de destructeurs. Dans
un constucteur ou dans un destructeur *this a toujours le type
statique de la classe à laquelle ce dtor|ctor appartient, donc init()
dans Object::Object appelle toujours Object::init

C´est une des petites differences entre C++ et Delphi (Object Pascal).
En Delphi c'est le constructeur FILS qui appelle le constructuer PERE
(inherited init) dans son code. En C++ le constructeur FILS est appelé
par le système avant l'exécution du constructeur FILS, c.a.d. en
Delphi l'objet a déjà le type FILS quand le constructeur de PERE est
appelé, tandis qu'en C++ l´objet a encore de type PERE quand le
constructeur de PERE est appelè.

--
Horst


Back to top
Alexandre
Guest





PostPosted: Fri Apr 15, 2005 5:27 pm    Post subject: Re: virtual Reply with quote

Quote:
normalement, "this" représente l'objet dynamique, donc, normalement
this->init () se trouvant
dans Object devrait faire appel à NewObject::init et non à Object::init.

Mais Object::init n'est pas appelable car virtuelle pure. Tu as un message
du type "Pure virtual fonction call" ?

Quote:
~Object (void) {
this->destroy ();
cout << "Object::~Object" << endl;
}

le destructeur doit être virtuel ici.




Back to top
Franck Branjonneau
Guest





PostPosted: Fri Apr 15, 2005 9:09 pm    Post subject: Re: virtual Reply with quote

"Alexandre" <alex.g (AT) netcourrier (DOT) com> écrivait:

Quote:
le destructeur doit être virtuel ici.

Pourquoi ?
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>

Back to top
Falk Tannhäuser
Guest





PostPosted: Fri Apr 15, 2005 9:13 pm    Post subject: Re: virtual Reply with quote

Stephane Wirtel wrote:
Quote:
Vincent Lascaux a écrit :
J'imagine que le contexte est plus complexe, mais pourquoi ne pas
mettre le code d'init dans le constructeur de NewObject et celui de
destroy dans son destructeur ?
Parce que j'essaie de surcharger new, new[], delete, delete[] via un
malloc & free, afin d'essayer de créer un memory manager
et qu'à ce moment là, le new n'appellera plus le constructeur de la
classe que j'instancie.
Voilà pourquoi un init et un destroy.

???

Comprends pas...
Tu veux dire que dans le programme suivant :
_______________________________________________________________________________
#include <iostream>
#include <ostream>
#include <cstdlib>
#include <cassert>

class B
{
protected:
int i;
public:
B(int i) : i(i) { std::cout << "B::B (" << i << ") at " << this << 'n'; }
virtual ~B() { std::cout << "B::~B(" << i << ") at " << this << 'n'; }
}; // class B

class D : public B
{
public:
D(int i) : B(i) { std::cout << "D:Very Happy (" << i << ") at " << this << 'n'; }
~D() { std::cout << "D::~D(" << i << ") at " << this << 'n'; }
}; // class D

void* operator new(std::size_t size)
{
void* p = std::malloc(size);
assert(p != 0);
std::cout << "operator new(" << size << ") returns " << p << 'n';
return p;
} // operator new()

void operator delete(void* p)
{
std::cout << "operator delete(" << p << ")n";
std::free(p);
} // operator delete()

int main()
{
delete new D(42);
return 0;
} // main()
_______________________________________________________________________________

les constructeurs et destructeurs ne sont pas appelés ? (Il peut arriver que
le destructeur de D n'est pas appelé si on oublie de rendre le destructeur
de B virtuel [ => comportement indéfini], mais cela n'a rien à voir avec la
redéfinition de new et delete.)
Chez moi cela affiche
_________________________________
operator new(Cool returns 0xa050278
B::B (42) at 0xa050278
D:Very Happy (42) at 0xa050278
D::~D(42) at 0xa050278
B::~B(42) at 0xa050278
operator delete(0xa050278)
_________________________________


Falk

Back to top
Thomas Labourdette
Guest





PostPosted: Sat Apr 16, 2005 8:09 am    Post subject: Re: virtual Reply with quote

Franck Branjonneau a écrit le Vendredi 15 Avril 2005 23:09 :

Quote:
"Alexandre" <alex.g (AT) netcourrier (DOT) com> écrivait:

le destructeur doit être virtuel ici.

Pourquoi ?

parcequ'autrement c'est le destructeur de l'objet de base qui est appelé.
Comme dans :
{
Object *p=new DerivedObject();
delete p;
}

@+
--
Heinrich IDÉKI-LAHULA (nordiste) (signature aléatoire)
" L'église est proche, mais la route est verglacée. Le bar est loin,
mais je marcherai avec prudence. " (Proverbe russe)


Back to top
James Kanze
Guest





PostPosted: Sat Apr 16, 2005 10:10 am    Post subject: Re: virtual Reply with quote

Thomas Labourdette wrote:
Quote:
Franck Branjonneau a écrit le Vendredi 15 Avril 2005 23:09 :

"Alexandre" <alex.g (AT) netcourrier (DOT) com> écrivait:

le destructeur doit être virtuel ici.

Pourquoi ?

parcequ'autrement c'est le destructeur de l'objet de base qui est appelé.
Comme dans :
{
Object *p=new DerivedObject();
delete p;
}

Parce qu'autrement, c'est un comportement indéfini. Qui
éventuellement provoque un crash du programme.

--
James Kanze mailto: [email]james.kanze (AT) free (DOT) fr[/email]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
Franck Branjonneau
Guest





PostPosted: Sun Apr 17, 2005 8:12 pm    Post subject: Re: virtual Reply with quote

James Kanze <kanze@none> écrivait:

Quote:
Thomas Labourdette wrote:

parcequ'autrement c'est le destructeur de l'objet de base qui est appelé.
Comme dans :
{
Object *p=new DerivedObject();
delete p;
}

Parce qu'autrement, c'est un comportement indéfini. Qui
éventuellement provoque un crash du programme.

Comme rappelé par Falk, oui. Mais le code de l'OP était :

struct B {

virtual void foo() { // Faire quelque chose }

};

struct D:B {

virtual void foo() { // Faire autre chose }

};

int
main() {

D obj;
// J'ajoute
B & ref_obj(obj);
}

J'ai un comportement indéfini là ? Pourquoi, le cas échéant ?
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Apr 18, 2005 8:01 am    Post subject: Re: virtual Reply with quote

Franck Branjonneau wrote:
Quote:
James Kanze <kanze@none> écrivait:

Thomas Labourdette wrote:

parcequ'autrement c'est le destructeur de l'objet de base
qui est appelé.

Comme dans :
{
Object *p=new DerivedObject();
delete p;
}

Parce qu'autrement, c'est un comportement indéfini. Qui
éventuellement provoque un crash du programme.

Comme rappelé par Falk, oui.

Je n'avais pas vu tout le thread. Je répondais seulement à une
assertation fausse. Il n'y a aucune garantie que le destructeur
de l'objet de base serait appelé, et surtout, ce n'est pas le
seul effet désagréable.

Quote:
Mais le code de l'OP était :

struct B {

virtual void foo() { // Faire quelque chose }

};

struct D:B {

virtual void foo() { // Faire autre chose }

};

int
main() {

D obj;
// J'ajoute
B & ref_obj(obj);
}

J'ai un comportement indéfini là ? Pourquoi, le cas échéant ?

Je n'avais pas vu le thread avant, mais maintenant que je l'ai
vu, ce n'était pas ça le code de l'OP. Le code de l'OP avait une
fonction virtuelle pûre, qu'on appelait dans le constructeur de
la classe de base. Donc aussi un comportement indéfini.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.