考虑以下无效的 C++ 代码。
#include <assert.h>
class NodeInterface {
public:
virtual ~NodeInterface () {}
virtual int f (const int& n) const = 0;
};
class ChildNodeInterface : public NodeInterface {
public:
virtual ~ChildNodeInterface () {}
};
class ParentNodeInterface : public NodeInterface {
public:
virtual ~ParentNodeInterface () {}
};
class ChildNode : public ChildNodeInterface {
public:
virtual ~ChildNode () {}
virtual int f (const int& n) const {
return 2*n;
}
};
class ParentNode : public ParentNodeInterface, private ChildNodeInterface {
public:
explicit ParentNode () :
mChild (new ChildNode ())
{
}
virtual ~ParentNode () {}
ChildNodeInterface* GetChildHandle () {
return this;
}
virtual int f (const int& n) const {
return 3*n;
}
private:
ChildNode* const mChild;
// How do I specify that I would like to override ChildNodeInterface::f?
virtual int f (const int& n) const { // On MSVC2010: C2535 member function already defined or declared
return 1 + mChild->f (n);
}
};
int main()
{
ParentNode parent;
assert (parent.f (2) == 6);
ChildNode node;
assert (node.f (2) == 4);
ChildNodeInterface* child (parent.GetChildHandle ());
assert (child->f (2) == 5);
return 0;
}
我的目标是让 ParentNode
私下看起来像 ChildNode
,这样它就可以在 ChildNode
之上添加一些附加功能” ChildNodeInterface
的实现。因此,ParentNode
可以有效地被视为变相的 ChildNode
句柄,这由 GetChildHandle
的简单性表明。
显然,如果ParentNode
不会重复继承NodeInterface
,就不会有问题。这样一来,人们就可以轻松地消除覆盖的歧义。下面的正确示例说明了这一点:
#include <assert.h>
class ChildNodeInterface {
public:
virtual ~ChildNodeInterface () {}
virtual int ChildMethod (const int& n) const = 0;
};
class ParentNodeInterface {
public:
virtual ~ParentNodeInterface () {}
virtual int ParentMethod (const int& n) const = 0;
};
class ChildNode : public ChildNodeInterface {
public:
virtual ~ChildNode () {}
virtual int ChildMethod (const int& n) const {
return 2*n;
}
};
class ParentNode : public ParentNodeInterface, private ChildNodeInterface {
public:
explicit ParentNode () :
mChild (new ChildNode ()),
mValue (1)
{
}
ChildNodeInterface* GetChildHandle () {
return this;
}
virtual int ParentMethod (const int& n) const {
return 3*n;
}
private:
ChildNode* const mChild;
const int mValue;
virtual int ChildMethod (const int& n) const {
return mValue + mChild->ChildMethod (n);
}
};
int main()
{
ParentNode parent;
assert (parent.ParentMethod (2) == 6);
ChildNode node;
assert (node.ChildMethod (2) == 4);
ChildNodeInterface* child (parent.GetChildHandle ());
assert (child->ChildMethod (2) == 5);
return 0;
}
但是,在 ParentNodeInterface
和 ChildNodeInterface
都继承自 NodeInterface
的特殊情况下,就会出现歧义。
从 main
中的断言可以清楚地看出,我的目标不是 NodeInterface
的虚拟继承。我的目的是在 ParentNode
中拥有真正不同的 NodeInterface::f
实现。
我想知道如何(如果可能)区分 ParentNodeInterface::f
和 ChildNodeInterface::f
在 ParentNode
中的实现。
最佳答案
我认为你的设计是错误的。您继承了 ChildNodeInterface 并且您的 ParentNode 类中有一个 ChildNode 成员?
Inherited ChildNodeInterface 不允许您使用 f 函数实现,因为 ChildNode 类不在继承树中。
C++ 不允许对具有相同签名的函数进行两次重新定义。因此编写同一个虚函数的 2 个实现是不可能的。
所以你有两个选择:
- [最佳] 尝试以正确的方式使用继承重新定义类设计。菱形继承(钻石问题)通常是由于糟糕的设计造成的。
[最快]从 ChildNodeInterface 中删除继承,并更喜欢在 ParentNode::f() 函数中调用 mChild->f() 来将 Child 行为添加到父节点:
虚拟 int f (const int& n) const { 返回 3*n + mChild->f(n); } 但我不知道这是否是您想要的行为。
关于c++ - 如何消除重复继承的基类中重写虚拟变量的歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12086777/