3

I'm seeing very different behavior in how C++ and Python handle the diamond inheritance scenario.

For the following two code snippets, the logic is the same but the output is different. I don't understand why. I'd really appreciate it if someone could offer some insight.

Python prints out "B B"

class A(object):
    def foo(self):
        print 'A'

class B(A):
    def foo(self):
        print 'B'
    def bar(self):
        self.foo()

class C(A):
    def foo(self):
        print 'C'
    def bar(self):
        self.foo()

class D(B, C):
    def bar(self):
        B.bar(self)
        C.bar(self)

D().bar()

But C++ prints out "B C"

struct A
{   
    virtual void foo() {
        cout << "A" << endl;
    }   
};  

struct B : public A
{   
    virtual void foo() {
        cout << "B" << endl;
    }   

    virtual void bar() { this->foo(); }
};  

struct C : public A
{   
    virtual void foo() {
        cout << "C" << endl;
    }   

    virtual void bar() { this->foo(); }
};  

struct D : public B, public C
{   
    virtual void bar() {
        B::bar();
        C::bar();
    }   
};  

int main()
{   
    D().bar();
} 

When I add the line cout << typeid(*this).name() << endl; to every bar() method above in C++, this is what gets printed out:

B 0x7fff803d9b70
C 0x7fff803d9b78
D 0x7fff803d9b70

It seems that B and D share the same address, but C is in a different vtable.

Edit

As suggested in the reply @JoranBeasley, I tried the following checks for the python code:

D.foo == B.foo
D.foo == C.foo
D.foo is B.foo
D.foo is C.foo

Python 2.7 prints out True False False False

Python 3.4 prints out True False True False

It seems that both B.foo and D.foo are the same method by value in both python 2 and 3, but python 2 makes a copy while python 3 doesn't.

7
  • If you want python-like inheritance in C++, you need to use virtual inheritance. Commented Jul 1, 2015 at 0:56
  • 2
    This C++ is not a real diamond: D has 2 different inherited A bases. Commented Jul 1, 2015 at 0:58
  • @o11c: I actually want the other way around: C++ behavior is preferred. Commented Jul 1, 2015 at 0:59
  • It is a good question. You can read a few points from this stackoverflow.com/questions/12457603/… Commented Jul 1, 2015 at 1:05
  • @BhargavRao that's a really good post. Thx! Commented Jul 1, 2015 at 1:08

1 Answer 1

4

I can only explain the python bits ...

C.bar(self)

passes the instance of D that you created in as self

so when it calls self.foo() it is no different than if you had said self.foo() inside of D.bar (i.e self remains staticly the same thing)

since inheritance is done Right to Left B.foo shadows C.foo

D.foo is B.foo # should print True
D.foo is C.foo # should print false

you could of coarse always call

C.foo(self) #prints C as expected

this really has nothing to do with Python multiple inheritance method resolution order since that is handled with the super() call ... instead you are trying to explicitly call your parent class methods, rather than allowing python to resolve them for you implicitly

as far as why its different than C++ , its because it is two seperate languages that implemented inheritance and multiple inheritance in distinct ways...

as mentioned in the comments you could change D's definition to

class D(C,B):
     ...

then D().foo() will print C

Sign up to request clarification or add additional context in comments.

11 Comments

Also mention that if he changes the order of inheritance (class D(B, C):) to (class D(C, B):) it will print C C ;) (after you have explained right-to-left inheritance)
Thanks for the answer. But both lines print out False.
@JimJarvis Could you please mention the Python version?
@JimJarvis Aha. That is the reason. Joran's answer is in Python3.
im sure its something about inheriting for object in python3 it is automagic ... in python2 it has to be explicit
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.