Connecting Tech Pros Worldwide Help | Site Map

confusion with abstract methods.

TheFerryman
Guest
 
Posts: n/a
#1: Jul 22 '05
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;
}
Marcin Kalicinski
Guest
 
Posts: n/a
#2: Jul 22 '05

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




TheFerryman
Guest
 
Posts: n/a
#3: Jul 22 '05

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.

Marcin Kalicinski
Guest
 
Posts: n/a
#4: Jul 22 '05

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




TheFerryman
Guest
 
Posts: n/a
#5: Jul 22 '05

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.

Rolf Magnus
Guest
 
Posts: n/a
#6: Jul 22 '05

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".

Rolf Magnus
Guest
 
Posts: n/a
#7: Jul 22 '05

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".

Closed Thread