我看到C ++和Python如何处理钻石继承场景的行为非常不同。
对于以下两个代码片段,逻辑是相同的但输出是不同的。我不明白为什么。如果有人能提供一些见解,我真的很感激。
Python打印出“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()
但C ++打印出“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();
}
当我在C ++中为上面的每个cout << typeid(*this).name() << endl;
方法添加行bar()
时,这就是打印出来的内容:
B 0x7fff803d9b70
C 0x7fff803d9b78
D 0x7fff803d9b70
似乎B
和D
共享相同的地址,但C
位于不同的vtable中。
修改
正如回复@JoranBeasley所建议的,我尝试了以下对python代码的检查:
D.foo == B.foo
D.foo == C.foo
D.foo is B.foo
D.foo is C.foo
Python 2.7打印出True False False False
Python 3.4打印出True False True False
似乎B.foo
和D.foo
在python 2和3中都是相同的方法,但是python 2会生成副本,而python 3则不会。
答案 0 :(得分:3)
我只能解释python位......
C.bar(self)
将您创建的D实例传递为self
所以当它调用self.foo()
时,与self.foo()
内部D.bar
内部self
所说的情况没有什么不同(即B.foo
仍然是静态相同的事情)
因为继承是从右到左C.foo
阴影D.foo is B.foo # should print True
D.foo is C.foo # should print false
C.foo(self) #prints C as expected
你可以粗略地打电话
super()
这与Python多重继承方法解析顺序无关,因为它是用class D(C,B):
...
调用处理的......相反,你试图显式调用你的父类方法,而不是让python来解决它们对你暗示
至于为什么它与C ++不同,因为它是两种独立的语言,以不同的方式实现了继承和多重继承...
如评论中所述,您可以将D的定义更改为
D().foo()
然后C
将打印@Scripts.Render("bundles/js/app")
if (User.IsInRole("Admin") {
Scripts.Render("bundles/js/admin")
}