c ++将接口连接到基类

时间:2013-04-15 06:01:04

标签: c++ interface

我的设计存在问题。

/// Generic class. Not owned by myself
class Node
{
    add(Node* v) { /* do somthing */ }
 };

/// interface writtern by myself
class ImyNode
{
    add(ImyNode* v) = 0;

    /// More functions
};

/// Implement ImyNode, use Node for implementation of SOME functions. 
class myNode:
    public ImyNode,
    public Node
{
    add(ImyNode* v) { Node::add(v); } // Error: ImyNode is not a type of Node
};

错误当然是正确的。那里并不奇怪。 但我需要一个解决方案。如何解决此编译错误。

我有4条建议:

  1. 在函数myNode :: add()
  2. 中使用reinterpret_cast运算符
  3. 创建一个inface INode并让ImyNode扩展此INode
  4. 将ImyNode :: add(ImyNode * v)更改为ImyNode :: add(myNode * v)
  5. 让ImyNode扩展Node
  6. 所有4条建议对我来说都是不可接受的。为什么呢?

    1. 不行。丑陋。不好主意
    2. 如果我没有Node怎么办?如果类层次结构比那么复杂呢?
    3. 接口不应该知道有关其派生类的任何信息
    4. 不喜欢接口扩展非接口类。即使我走这条路,如何在没有ImyNode CTOR的情况下调用Node CTOR
    5. 如果有人有更好的设计或优雅的解决方案,或者可以说服我,我的建议是好的,请做。

      感谢。

2 个答案:

答案 0 :(得分:1)

您的层次结构已损坏,您需要重新考虑它。

如果有人以您不期望的方式延长ImyNode

,该怎么办?
class IUnexpectedNode : public ImyNode {}; // note: not inheriting Node

然后拨打您的myNode::add

IUnexpectedNode unexpected;
myNode my;
my.add(unexpected);

您将无法履行您的义务。

<强>更新

如果您认为每个ImyNode最终也是Node,则履行义务的最简单方法是更改​​ImyNode::add()的签名。

class ImyNode
{
  virtual void add(Node*) = 0; // This method follows the Node::add(Node*) 
                               // signature, although the classes are unrelated.
                               // The intent is that each class that implements 
                               // ImyNode also extends Node, so the two methods 
                               // merge into one.

};

答案 1 :(得分:1)

在您的设计中,您应该使用某种访问者模式,我的意思是将所有派生节点放在您的界面中。其他解决方案是使用动态强制转换和/或ImyNode到Node的某些适配器。像那样:

  class myNode;
  class someOtherNode; // if any.  
  class ImyNode {
  public:
     virtual void add(myNode* node) = 0;
     virtual void add(someOtherNode* node) = 0;
   };

正如您所看到的,ImyNode在ImyNode中的添加是不可能的,您应该知道自己在做什么。如果没有比myNode更专业化的东西,那么摆脱你的界面,因为它结果是没用的。