0

Consider the following (my compiler is Visual Studio 2015):

class myClassA {
public:
    myClassA()
    {
        printf("Build A\n");
    }
    void parentMethod()
    {
        test();
    }
    virtual ~myClassA()
    {
        printf("Delete A\n");
    }
    virtual void test() = 0;
};

class myClassB : public myClassA {
public:
    myClassB()
    {
        printf("Build B\n");
    }
    virtual ~myClassB()
    {
        printf("Delete B\n");
    }
    void test()
    {
        printf("test\n");
    }
};

int main()
{
    myClassA *b = new myClassB();
    b->parentMethod();
    delete b;
    getchar();
    return 0;
}

If I run this, everything is fine:

Build A
Build B
test
Delete B
Delete A

But if I want to call test() inside the destructor, it won't compile!

virtual ~myClassA()
{
    printf("Delete A\n");
    test();
}

the linker complain:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "public: virtual void __thiscall myClassA::test(void)" (?test@myClassA@@UAEXXZ) referenced in function "public: virtual __thiscall myClassA::~myClassA(void)" (??1myClassA@@UAE@XZ)  PolymorphismTest    D:\dev\PolymorphismTest\PolymorphismTest\PolymorphismTest.obj   1   

why is that ?

it seems that a destructor cannot call a virtual method, wheras a regular method can.

  • `test()` in the derived class is not `virtual`. – ivan_pozdeev Apr 30 '17 at 10:42
  • @ivan_pozdeev It is virtual. It overrides the one from the base class. – juanchopanza Apr 30 '17 at 10:45
  • When you are in `~myClassA()` the `B` part has already been destroyed (as seen by "Delete B" in the output) and there is only an `A` part left. At that point you cannot use anything from `B`, because it's not there anymore. – Bo Persson Apr 30 '17 at 10:52
  • Just make A::test() non-abstract, no more linker error, and now you can easily tell that it is not going to do what you need it to do. – Hans Passant Apr 30 '17 at 10:53
  • @Bo Persson thanks, indeed, I didn't thought about the fact that B is dead at the time the destructor of A is called. It makes perfectly sense now. – Mike Dudley Apr 30 '17 at 11:34

0 Answers0