简体   繁体   English

Python与C ++中的多重继承

[英]Multiple inheritance in python vs c++

This is a Python and C++ question. 这是一个Python和C ++问题。

I am experimenting with multiple inhertiance and I came across this example. 我正在尝试多重继承,并且遇到了这个示例。

B1 B2
 \ /
  D

Say I have two (independent?) parent classes B1, B2 and one child class D . 说我有两个(独立的)父类B1, B2和一个子类D We're only interested in objects of class D . 我们只对class D对象感兴趣。

class B1:
    def f1(self):
        print "In f1"

class B2:
    def f2(self):
        self.f1()

class D (B1, B2):
    def fD(self):
        self.f2()

d = D()
d.fD()

Output: In f1

What's interesting (at least to me) is that class B2 has no knowledge about class B1 and yet f2 can call self.f1() with no problems. 有趣的是(至少对我而言)是, class B2不了解class B1 ,但是f2可以self.f1()调用self.f1()

I tried to replicate this exact thing in C++ and I couldn't make it work because I don't know how to call f1 from f2 . 我试图在C ++中复制这个确切的东西,但由于我不知道如何从f2调用f1 ,所以无法使其正常工作。

class B1 {
    public:
    virtual ~B1() {}
    virtual void f1() { cout << "In f1" << endl; }
};

class B2 {
    public:
    virtual ~B2() {}
    virtual void f2() { /* What goes here?? */ }
};

class D : public B1, public B2 {
    public:
    void fD() { f2(); }
};

So, I want to know how/why Python can handle this but C++ cannot? 因此,我想知道Python如何/为什么可以处理此问题,而C ++不能?

Also, what minimal changes can we make to the C++ code to make it behave like the Python code? 另外,我们可以对C ++代码进行哪些最小的更改以使其表现得像Python代码一样?

what minimal changes can we make to the C++ code to make it behave like the Python code? 我们可以对C ++代码进行哪些最小的更改以使其表现得像Python代码?

Short answer: You can't. 简短的回答:不能。 B2 has no idea that it's going to form part of a sub-class that also has B1 as super-class. B2不知道它将成为B1的子类的一部分。

Long answer: You can, if you use some grotty downcasting (essentially casting this to a D* ). 龙答:可以,如果你使用一些难看的向下转换(基本上是铸造thisD* )。 But it's probably not a good idea, as *this is not necessarily a D . 但这可能不是一个好主意,因为*this不一定是D

This works in python because the name f1 in class B2 is being resolved at runtime. 这在python中有效,因为在运行时解析了类B2的名称f1 This is "duck typing" -- the object reference in self just has to have a valid f1 to call, which it does when you construct it that way. 这就是“鸭式打字”- self的对象引用只需要具有一个有效的f1即可调用,就可以通过这种方式构造它。

The most C++-like way to get similar behavior in C++ is the Curiously recurring template pattern . 在C ++中获得类似行为的最类似于C ++的方式是Curiously recurring template pattern Your C++ version of B2 needs to know what it is a part of. 您的B2 C ++版本需要知道它的组成部分。 Making it a template of its derived type gives you a "clean" way to do the dynamic_cast that others have suggested. 使它成为其派生类型的模板,可以为您提供一种“干净”的方式来执行其他人建议的dynamic_cast It's cleaner because there will be a new class B2<T> for every class that derives from it. 之所以比较干净,是因为从它派生的每个类都会有一个新的类B2<T> Each specialization will have a distinct f2 which uses the right cast to get to the right f1 . 每个专长都有一个不同的f2 ,它使用正确的强制转换来获得正确的f1 It will work much like the python version in that the existence of a callable f1 is all that is required (at compile time rather than runtime, though). 它会像python版本一样工作,因为只需要存在一个可调用的f1 (尽管在编译时而不是在运行时)。

class B1 {
    public:
    virtual ~B1() {}
    virtual void f1() { cout << "In f1" << endl; }
};

template <typename Derived>
class B2 {
    public:
    virtual ~B2() {}
    virtual void f2() { dynamic_cast<Derived *>(this)->f1(); }
};

class D : public B1, public B2<D> {
    public:
    void fD() { f2(); }
};

I want to know how/why Python can handle this but C++ cannot? 我想知道为什么/为什么Python可以解决这个问题,但是C ++无法解决?

That's because Python is dynamically typed and C++ is statically typed. 那是因为Python是动态类型的,而C ++是静态类型的。

what minimal changes can we make to the C++ code to make it behave like the Python code? 我们可以对C ++代码进行哪些最小的更改以使其表现得像Python代码?

If you want to program in Python you know where to find it. 如果要使用Python编程,则知道在哪里可以找到它。 Programming in C++ using Python ways is counter-idiomatic and is generally frowned upon. 使用Python方式在C ++中进行编程是反习惯的,通常对此不予理会。 That said, if you want to do it anyway, you use dynamic_cast<B2*>(this) . 也就是说,如果仍然要执行此操作,请使用dynamic_cast<B2*>(this)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM