Multiple inheritance with only one virtual base destructor

Discussion in 'C++' started by Christian Hackl, Apr 27, 2007.

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


    --
    Christian Hackl
    Christian Hackl, Apr 27, 2007
    #1
    1. Advertising

  2. Christian Hackl wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Apr 27, 2007
    #2
    1. Advertising

  3. Victor Bazarov ha scritto:

    > Christian Hackl wrote:
    >> Does the following code produce undefined behaviour?

    >
    > No.


    Thank you!

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


    Thanks again for dispelling my doubts :)


    --
    Christian Hackl
    Christian Hackl, Apr 27, 2007
    #3
  4. Christian Hackl

    Zeppe Guest

    Christian Hackl wrote:
    > 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
    Zeppe, Apr 27, 2007
    #4
  5. Christian Hackl

    James Kanze Guest

    On Apr 27, 9:15 pm, Christian Hackl <> wrote:
    > 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.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 28, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page