这是一个Python和C ++问题。
我正在尝试多次无效,我遇到了这个例子。
B1 B2
\ /
D
假设我有两个(独立?)父类B1, B2
和一个子类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
有趣的是(至少对我而言)class B2
不了解class B1
,而f2
可以毫无问题地致电self.f1()
。
我试图在C ++中复制这个确切的东西而我无法使其工作,因为我不知道如何从f1
调用f2
。
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(); }
};
所以,我想知道Python如何/为什么要处理这个,但C ++不能?
此外,我们可以对C ++代码进行哪些最小的更改,使其行为类似于Python代码?
答案 0 :(得分:1)
我们可以对C ++代码进行哪些最小的更改,使其行为类似于Python代码?
简答:你做不到。 B2
不知道它将构成一个子类的一部分,该子类也有B1
作为超类。
答案很长:如果你使用一些粗鲁的向下转换(基本上将this
转换为D*
),你可以。但这可能不是一个好主意,因为*this
不一定是D
。
答案 1 :(得分:1)
这在python中有效,因为类f1
中的名称B2
正在运行时解析。这是“鸭子打字” - self
中的对象引用只需要有一个有效的f1
来调用,当你以这种方式构造它时就会这样做。
在C ++中获得类似行为的最类似C ++的方法是Curiously recurring template pattern。您的C ++版B2
需要知道它是什么的一部分。将其作为派生类型的模板,可以让您以“干净”的方式完成其他人建议的dynamic_cast
。它更干净,因为每个类都会有一个新的类B2<T>
。每个专精都会有一个不同的f2
,它使用正确的演员来到达f1
。它的工作方式与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(); }
};
答案 2 :(得分:0)
我想知道Python如何/为什么要处理这个但C ++不能?
这是因为Python是动态类型的,而C ++是静态类型的。
我们可以对C ++代码进行哪些最小的更改,使其行为类似于Python代码?
如果你想用Python编程,你知道在哪里找到它。使用Python方式在C ++中进行编程是反惯用的,并且通常不赞成。也就是说,如果你想要这样做,你可以使用dynamic_cast<B2*>(this)
。