【发布时间】:2012-08-23 07:30:23
【问题描述】:
考虑以下无效的 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 的真正不同的实现。
我想知道如何(如果可能)在ParentNode 中区分ParentNodeInterface::f 和ChildNodeInterface::f 的实现。
【问题讨论】: