Multiple inheritance with only one virtual base destructor

C

Christian Hackl

Does the following code produce undefined behaviour?

class Base
{
public:
virtual ~Base();
/* ... */
};

class BaseWithNonVirtualDestructor
{
protected:
~BaseWithNonVirtualDestructor();
/* ... */
}

class Derived : public Base, public BaseWithNonVirtualDestructor
{
public:
/* ... */
};

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


May you also point me to the section of the standard which defines the
behaviour of such MI constructs in conjunction with virtual destructors?


For my current problem, by the way, BaseWithNonVirtualDestructor is
actually boost::noncopyable, which I would like to use in this manner.
 
V

Victor Bazarov

Christian said:
Does the following code produce undefined behaviour?
No.


class Base
{
public:
virtual ~Base();
/* ... */
};

class BaseWithNonVirtualDestructor
{
protected:
~BaseWithNonVirtualDestructor();
/* ... */
}

class Derived : public Base, public BaseWithNonVirtualDestructor
{
public:
/* ... */
};

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


May you also point me to the section of the standard which defines the
behaviour of such MI constructs in conjunction with virtual
destructors?

I think you're looking for 5.3.5/3 and 12.4/7.
For my current problem, by the way, BaseWithNonVirtualDestructor is
actually boost::noncopyable, which I would like to use in this manner.

V
 
Z

Zeppe

Christian said:
Does the following code produce undefined behaviour?

In addiction to what Victor said, it also makes sense that your code
works properly: the virtual destructor is required to be able to
discover the dynamic type. So, as long as you deallocate from a base
class that has got the virtual destructor, you will be sure that the
destructor of the appropriate dynamic type will be allocated. That
destructor will call all the destructors of the base classes.

Regards,

Zeppe
 
J

James Kanze

Does the following code produce undefined behaviour?
class Base
{
public:
virtual ~Base();
/* ... */
};
class BaseWithNonVirtualDestructor
{
protected:
~BaseWithNonVirtualDestructor();
/* ... */
}
class Derived : public Base, public BaseWithNonVirtualDestructor
{
public:
/* ... */
};
int main()
{
Base *ptr = new Derived;
delete ptr;
}
May you also point me to the section of the standard which defines the
behaviour of such MI constructs in conjunction with virtual destructors?

Victor has answered the exact question. In fact, multiple
inheritance has nothing to do with it; if the static type of the
pointed to object in the delete has a virtual destructor, you're
OK; if it doesn't you're not.
For my current problem, by the way, BaseWithNonVirtualDestructor is
actually boost::noncopyable, which I would like to use in this manner.

Presumably, it makes no sense for people to manipulate your
object using boost::noncopyable*. So why not inherit privately
from the class, so they can't (except by means of a C-style
cast)? As your class now stands:

BaseWithNonVirtualDestructor* p = new Derived ;
delete p ;

*is* undefined behavior, and doesn't solitict the slightest
complaint on the part of the compiler.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top