Search code examples
c++inheritancepolymorphismmultiple-inheritance

c++: polymorphism + multiple inheritance order. Is the inheritace order significant?


I'm trying to solve a little mystery about the code similar to the following:

struct Interface {
    virtual void f () = 0;
}

struct SomeClass {
    virtual void additionalBehaviour () = 0;
    void g () {
        additionalBehavoiur ();
        /*Some stuff with printing into a ostringstream*/
    }
}

struct Derived : public SomeClass, public Interface {
    void additionalBehaviour () { /*Some printing to oss*/ }
    void f () { g (); }
}

int main () {
    unique_ptr<Interface> ifc (new Derived ());
    ifc->f ();
    cout << "HI!" << endl;
    return 0;
}

It works, but quits randomly causing с0000005 0a9e appcrash on Windows having done the things listed in g () partly and having printed "HI!".
So, at some point it stops printing into the file, finishes everything else and, finally, crashes. Some point means an indeed some point: for example, file << "phrase" may produce phra and nothing after that.
Also, it executes correctly and does not crash when executed in GDB. And there are no memory leaks according to Dr. Memory.

The solution:

struct Derived : public Interface, public SomeClass {
    void f () { g (); }
}

The question: why?!
I suppose it is something about the relative field positions in classes, but what about no crashing in GDB and no signs of memory problems then?


Solution

  • It seems that the problem is related to the fact that you have no virtual destructor. This is why the processing in g() is performed: the crash happens when unique_ptr to destroy the object.

    Like this it should work:

    struct Interface {
        virtual void f () = 0;
        virtual ~Interface() {};
    };
    

    Online demo

    Standard reference:

    5.3.5/3: In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.