2013-04-15 34 views
2

我的設計有問題。C++連接接口到基類

/// 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 
}; 

錯誤當然是正確的。那裏沒有驚喜。 但我需要一個解決方案。如何解決這個編譯錯誤。

我有四點建議:

  1. 在功能使用MYNODE reinterpret_cast運算符::加()
  2. 創建工程接口類的inode,讓ImyNode延長這個inode
  3. 變化ImyNode ::添加(ImyNode * v)至ImyNode ::添加(MYNODE * v)
  4. 讓ImyNode延長節點

所有的四個建議是不可接受的給我。爲什麼?

  1. 不起作用。醜陋。糟糕的主意
  2. 如果我不擁有節點?如果類層次更復雜那麼呢?
  3. 接口不應該知道任何關於它的派生類
  4. 不喜歡它的接口擴展非接口類。即便我走了這條路,我怎麼會叫節點CTOR沒有ImyNode CTOR

如果任何人有一個更好的設計和優雅的解決方案或能說服我,我的建議是好的,請執行下列操作之一。

謝謝。

+0

如果ÌmyNode'類是接口,爲什麼不讓'Node'繼承自此,而您的'myNode'只能繼承'Node'? –

+0

節點是一個通常我不擁有的泛型類(讓我們假設我希望避免Node中的任何更改,因爲它本身並不是我自己的,也不是太泛泛,ImyNode有一些特定的功能,通用Node不應該實現(或意識到) – idanshmu

+1

如果你想使用Node,那麼class myNode應該包含「Node」(應該是Is-a關係)而不是從它繼承 – Arun

回答

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

在你非常的設計,你應該使用某種訪問者模式的,我的意思是把所有衍生節點的接口。其他解決方案是使用動態轉換和/或從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更專業化的東西,那就擺脫你的界面,因爲它變得毫無用處。