Connecting Tech Pros Worldwide Help | Site Map

confusion with abstract methods.

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 22nd, 2005, 08:58 AM
TheFerryman
Guest
 
Posts: n/a
Default confusion with abstract methods.

Why doesn't compile? I would have thought the dtor of Base would call
Derived::f()

struct Base
{
virtual void f() = 0;

virtual ~Base(){f();}
};

struct Derived : public Base
{
virtual void f(){cout << "\nIn Derived f";}
};

int main()
{
Derived d;

return 0;
}

  #2  
Old July 22nd, 2005, 08:58 AM
Marcin Kalicinski
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

Uzytkownik "TheFerryman" <ferry@onthenet.com> napisal w wiadomosci
news:25h2705b3r6jk9obt5qtqfj20rdro1k876@4ax.com...[color=blue]
> Why doesn't compile? I would have thought the dtor of Base would call
> Derived::f()
>
> struct Base
> {
> virtual void f() = 0;
>
> virtual ~Base(){f();}
> };
>
> struct Derived : public Base
> {
> virtual void f(){cout << "\nIn Derived f";}
> };
>
> int main()
> {
> Derived d;
>
> return 0;
> }[/color]

Destructor of Base cannot call Derived::f(), because Derived does not exist
at this point. At Base::~Base, d is of class Base, because Derived
destructor was already executed. In general, virtual function call mechanism
does not work during construction/destruction phase. Imagine what would
happen if Base::~Base actually called Derived::f() - a method of object
would be called after its destructor has already executed! It would break
important C++ 'contract', which states that no operation can be performed on
object before constructor or after destructor.

Best regards,
Marcin




  #3  
Old July 22nd, 2005, 08:58 AM
TheFerryman
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

On Mon, 5 Apr 2004 13:58:24 +0200, "Marcin Kalicinski"
<kalita@poczta.onet.pl> wrote:
[color=blue]
>Uzytkownik "TheFerryman" <ferry@onthenet.com> napisal w wiadomosci
>news:25h2705b3r6jk9obt5qtqfj20rdro1k876@4ax.com.. .[color=green]
>> Why doesn't compile? I would have thought the dtor of Base would call
>> Derived::f()
>>
>> struct Base
>> {
>> virtual void f() = 0;
>>
>> virtual ~Base(){f();}
>> };
>>
>> struct Derived : public Base
>> {
>> virtual void f(){cout << "\nIn Derived f";}
>> };
>>
>> int main()
>> {
>> Derived d;
>>
>> return 0;
>> }[/color]
>
>Destructor of Base cannot call Derived::f(), because Derived does not exist
>at this point. At Base::~Base, d is of class Base, because Derived
>destructor was already executed. In general, virtual function call mechanism
>does not work during construction/destruction phase. Imagine what would
>happen if Base::~Base actually called Derived::f() - a method of object
>would be called after its destructor has already executed! It would break
>important C++ 'contract', which states that no operation can be performed on
>object before constructor or after destructor.
>
>Best regards,
>Marcin
>
>
>[/color]

Ah yes! I see that now. Thanks for your explanation.

  #4  
Old July 22nd, 2005, 08:58 AM
Marcin Kalicinski
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

Uzytkownik "TheFerryman" <ferry@onthenet.com> napisal w wiadomosci
news:25h2705b3r6jk9obt5qtqfj20rdro1k876@4ax.com...[color=blue]
> Why doesn't compile? I would have thought the dtor of Base would call
> Derived::f()
>
> struct Base
> {
> virtual void f() = 0;
>
> virtual ~Base(){f();}
> };
>
> struct Derived : public Base
> {
> virtual void f(){cout << "\nIn Derived f";}
> };
>
> int main()
> {
> Derived d;
>
> return 0;
> }[/color]

Destructor of Base cannot call Derived::f(), because Derived does not exist
at this point. At Base::~Base, d is of class Base, because Derived
destructor was already executed. In general, virtual function call mechanism
does not work during construction/destruction phase. Imagine what would
happen if Base::~Base actually called Derived::f() - a method of object
would be called after its destructor has already executed! It would break
important C++ 'contract', which states that no operation can be performed on
object before constructor or after destructor.

Best regards,
Marcin




  #5  
Old July 22nd, 2005, 08:58 AM
TheFerryman
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

On Mon, 5 Apr 2004 13:58:24 +0200, "Marcin Kalicinski"
<kalita@poczta.onet.pl> wrote:
[color=blue]
>Uzytkownik "TheFerryman" <ferry@onthenet.com> napisal w wiadomosci
>news:25h2705b3r6jk9obt5qtqfj20rdro1k876@4ax.com.. .[color=green]
>> Why doesn't compile? I would have thought the dtor of Base would call
>> Derived::f()
>>
>> struct Base
>> {
>> virtual void f() = 0;
>>
>> virtual ~Base(){f();}
>> };
>>
>> struct Derived : public Base
>> {
>> virtual void f(){cout << "\nIn Derived f";}
>> };
>>
>> int main()
>> {
>> Derived d;
>>
>> return 0;
>> }[/color]
>
>Destructor of Base cannot call Derived::f(), because Derived does not exist
>at this point. At Base::~Base, d is of class Base, because Derived
>destructor was already executed. In general, virtual function call mechanism
>does not work during construction/destruction phase. Imagine what would
>happen if Base::~Base actually called Derived::f() - a method of object
>would be called after its destructor has already executed! It would break
>important C++ 'contract', which states that no operation can be performed on
>object before constructor or after destructor.
>
>Best regards,
>Marcin
>
>
>[/color]

Ah yes! I see that now. Thanks for your explanation.

  #6  
Old July 22nd, 2005, 08:59 AM
Rolf Magnus
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

Marcin Kalicinski wrote:
[color=blue]
> Destructor of Base cannot call Derived::f(), because Derived does not
> exist at this point. At Base::~Base, d is of class Base, because
> Derived destructor was already executed. In general, virtual function
> call mechanism does not work during construction/destruction phase.[/color]

Actually, it does work. You just have to remember that the object isn't
of the Derived class anymore in the Base destructor. There is a
difference. Think of the following example:

#include <iostream>

class Base
{
public:
virtual void foo() { std::cout << "Base\n"; }
void x () { foo(); }
};

class Derived : public Base
{
public:
void foo() { std::cout << "Derived\n"; }
~Derived() { x(); }
};

class Another : public Derived
{
public:
void foo() { std::cout << "Another\n"; }
};

int main()
{
Another a;
}

The output of this program would be "Base" if polymorphism wouldn't work
in the destructor, but it does print "Derived".

  #7  
Old July 22nd, 2005, 08:59 AM
Rolf Magnus
Guest
 
Posts: n/a
Default Re: confusion with abstract methods.

Marcin Kalicinski wrote:
[color=blue]
> Destructor of Base cannot call Derived::f(), because Derived does not
> exist at this point. At Base::~Base, d is of class Base, because
> Derived destructor was already executed. In general, virtual function
> call mechanism does not work during construction/destruction phase.[/color]

Actually, it does work. You just have to remember that the object isn't
of the Derived class anymore in the Base destructor. There is a
difference. Think of the following example:

#include <iostream>

class Base
{
public:
virtual void foo() { std::cout << "Base\n"; }
void x () { foo(); }
};

class Derived : public Base
{
public:
void foo() { std::cout << "Derived\n"; }
~Derived() { x(); }
};

class Another : public Derived
{
public:
void foo() { std::cout << "Another\n"; }
};

int main()
{
Another a;
}

The output of this program would be "Base" if polymorphism wouldn't work
in the destructor, but it does print "Derived".

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,840 network members.