2012-01-23 71 views
8
/*Child is inherited from Parent*/ 
class Parent { 
    public: 
    Parent() //Constructor 
    { 
     cout << "\n Parent constructor called\n" << endl; 
    } 
    protected: 
    ~Parent() //Dtor 
    { 
     cout << "\n Parent destructor called\n" << endl; 
    } 
}; 

class Child : public Parent 
{ 
    public: 
    Child() //Ctor 
    { 
     cout << "\nChild constructor called\n" << endl; 
    } 
    ~Child() //dtor 
    { 
     cout << "\nChild destructor called\n" << endl; 
    } 
}; 

int main() 
{ 
    Parent * p2 = new Child;   
    delete p2; 
    return 0; 
} 

如果我使Parent的析构函数为虚拟的,那么我得到一个错误,那么使受保护的析构函数成为虚拟的目的是什么?有没有用于使受保护的析构函数虚拟?

+1

也许我们应该从“为什么要让dtor保护?”开始。 –

+4

你为什么想要使析构函数为虚拟?不应该*你*知道目的?受保护的析构函数意味着对象不应该通过基本指针被破坏,所以'main'中的代码是错误的。 – thiton

+0

请参阅http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – user998692

回答

17

举一个例子:假设你有一个实现引用计数的基类。如果(只有,如果)内部计数器通过调用release达到零,则您有一个addRefrelease方法,并且希望将对象销毁。

所以,首先你要保护你的析构函数(因为你只想破坏relase中的对象)。

如果你打算从你的类派生,你也希望你的析构函数是虚拟的,因为当你想通过指向基类的指针销毁一个子对象时,你需要一个虚拟析构函数(谢谢@sharptooth提示...)

+2

不,你需要一个虚拟析构函数,而不管派生类是否需要额外的销毁,否则行为只是未定义的。 – sharptooth

+0

@sharptooth对,我没有想到这一点。修好了,谢谢指出! – MartinStettner

+0

我看到一些使用这个技巧的代码强制所有销毁都通过朋友C风格的包装函数(根据派生类定义)。我想这个意图是相似的,但是在维护中失去了意义。 – Muxecoid

4

protected: Base::~Base();应该虚拟至少如果你(上图)或删除派生类的BaseBaseBase衍生的任何对象。

+0

删除此;对于任何未知的孩子对象 得到它的感谢 – tusharfloyd

+0

@ user1085822:所以,你感谢我,而不接受我的答案。你想告诉我什么? – bitmask

+0

不应该只是 – ksb

5

是的,如果你打算在class Parent中执行delete this成员函数,这在COM对象中实现IUnknown::Release()时非常常见。

+0

不错。对于这个问题,如果有'depete pBase;'attampted的话,其他派生类。 – iammilind

相关问题