2

我的设计有问题。

/// 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() 中使用 reinterpret_cast 运算符
  2. 创建一个接口 INode 并让 ImyNode 扩展这个 INode
  3. 将 ImyNode::add(ImyNode* v) 更改为 ImyNode::add(myNode* v)
  4. 让 ImyNode 扩展 Node

所有 4 条建议对我来说都是不可接受的。为什么?

  1. 不会工作。丑陋的。馊主意
  2. 如果我没有 Node 怎么办?如果类层次结构比那更复杂怎么办?
  3. 接口不应该知道任何关于它的派生类
  4. 不喜欢接口扩展非接口类。即使我确实走这条路,如果没有 ImyNode CTOR,我将如何调用 Node CTOR

如果有人有更好的设计或优雅的解决方案,或者可以说服我我的建议之一是好的,请这样做。

谢谢。

4

2 回答 2

1

你的层次结构被打破了,你需要重新考虑它。

如果有人ImyNode以你没想到的方式延伸怎么办

class IUnexpectedNode : public ImyNode {}; // note: not inheriting Node

然后打电话给你的myNode::add

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

届时您将无法履行您的义务。

更新

如果假设 everyImyNode最终也是 a 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.

};
于 2013-04-15T06:31:58.290 回答
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 更多的专业化,那么摆脱你的接口,因为它被证明是无用的。

于 2013-04-15T07:49:31.143 回答