次の無効な 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
。NodeInterface::f
inの真に異なる実装を持つことが私の意図ParentNode
です。ParentNodeInterface::f
の実装とChildNodeInterface::f
inをどのように(可能であれば)区別できるのだろうかParentNode
。