C++ is Virtual destructor still needed if there are no data members in derived?

谁说胖子不能爱 提交于 2019-12-23 07:33:34

问题


Suppose I have this code

class Base{
  public:
        int getVal();
  private:
         int a, b;
};

class Derived::public Base{
    public:
         void printVal();
};

int main(){
    Base *b = new Derived();
    delete b;    
}

I know a virtual destructor would delete things properly, but is it bad to delete with base pointer (when there is no virtual destructor) even if there are no virtual functions and no data members in the derived class? What will happen if this is done?


回答1:


For primitive-type data, your example will most likely work in practice. As a matter of fact, incurring a vtable could actually hinder performance (so there may be some legitimate use here), but it is technically undefined, per 5.3-5.4:

If the static type of the operand [of the delete operator] is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behaviour is undefined.

It really all depends on the "heapness" of the data in your class, and as there are no heap-allocated members (in your case), you should be fine, but it's definitely a code smell.




回答2:


Is it bad to delete with base pointer (when there is no virtual destructor) even if there are no virtual functions and no data members in the derived class?

Yes.

The behavior is undefined regardless the contents of the derived class.

What will happen if this is done?

Anything could happen.




回答3:


The virtual desctructor in the derived class is needed in order to properly call the derived destructor (polymorphism), when the derived object is created through a pointer to the base class.

High Integrity CPP Rule 3.3.2 Write a 'virtual' destructor for base classes. (QACPP 2116)

Justification: If an object will ever be destroyed through a pointer to its base class, then that base class should have a virtual destructor. If the base class destructor is not virtual, only the destructor for the base class will be invoked. In most cases, destructors should be virtual, because maintenance or reuse may add derived classes that require a virtual destructor.

class Base {}; 
class Derived : public Base { public: ~Derived() {} }; 

void foo() {  
   Derived* d = new Derived; delete d; // correctly calls derived destructor 
} 
void boo() { 
   Derived* d = new Derived; Base* b = d; delete b; // problem! does not call derived destructor! 
}


来源:https://stackoverflow.com/questions/3944806/c-is-virtual-destructor-still-needed-if-there-are-no-data-members-in-derived

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!