2013-04-21 175 views
0

比方說,我們有一個集合類,如:覆蓋功能參數/

class CCollection { 

public: 
    void add(B& b); 
    void remove(B& b); 
    void doSomethingWithAllObjects(); 

protected: 
    std::vector<B*> bs; 

} 

其中B是一個抽象類和

doSomethingWithAllObjects(); 

具體行爲取決於具體的B型,通話它C.

有沒有一種方法來推導CCollection,讓方法

add(B b); 
remove(B b); 

只接受派生類型?

我想到了什麼樣覆蓋這樣的方法:

class D : A{ 
public: 
    void add(C c); 
    void remove(C c); 
    void doSomethingWithAllObjects(); 
private: 
    std::vector<B*> bs;  
} 

或通用javaish構建像

template<class T : B> 
class C { 
    ...//do lots of stuff 
} 

推導幾乎是100%相同。但是你不能混用不同的B派生。

我已經讀過幾乎不可能將模板類限制到某些類型,但必須有一種方法來避免爲每個B的派生編寫一個整體類。重點是,我需要在B中定義的功能,所以我不能用一個簡單的模板

template<class T> 
class B{ 
    .... 
} 

我當然可以假設其他程序員只是交出正確類型的權利CCollection但是這不能成爲精神。我想要的是強制其他程序員只添加一種類型的Bs。

+0

歡迎來到Stack Overflow!如果我正確地閱讀你的問題,似乎有一個基本的設計問題。虛擬函數允許在* runtime *處確定行爲。並且,在運行時條件已知之前,更改該參數的類型將在編譯時執行。你希望在編譯時執行什麼? – 2013-04-21 16:41:11

+0

只接受派生類型?是不是基類抽象?你不能聲明它的一個對象。那麼你怎麼能通過它來添加和刪除?我在這裏錯過了什麼嗎? – stardust 2013-04-21 16:44:12

+0

我不確定你是如何從值參數'add(B b)'轉換成一個存儲在你的向量中的指針'std :: vector '似乎你可以採取的唯一的地址是參數的死亡地址函數結尾'add()' – 2013-04-21 16:46:03

回答

0

我不知道如果我理解正確的,但我想你loooking一個簡單模板非成員函數型。模板函數可以用來確保類型匹配。

template<typename T> 
void global_adder(const T& cl, const T& toadd) { 
    cl.add(toadd); 
} 
  • 由於沒有做基於遺產類型扣減,這將 確保A不添加到B或B到C等。要加入 這兩個參數必須具有相同的類型。而已。

  • 只將您的類方法保留在基類中。製作它 protected並添加此功能爲friend

  • 這樣,你現在沒有人可以調用從 別的地方a.addb.add將不能夠在不同類型添加到一定 類)。

  • 添加或刪除元素的唯一方法是通過模板 確保類型匹配的函數。

+0

完美的作品。謝謝! – 2013-04-21 20:16:05

-1

你可以像

class BaseCollection { 
    public: 
    void doSomethingWithAllObjects(); 
    protected: 
    void addInternal(B* b); // consumes the element 

    std::vector<B*> bs; // or better use vector<shared_ptr> for reference count 
}; 

template <typename C> 
class Collection : public BaseCollection { 
    public: 
    void add(const C& c) { 
     C* my_copy = new C(c); // suppose we have a copy constructor 
     addInternal(my_copy); 
    } 
}; 

一個抽象基類集合如果您嘗試實例Collection<C>其中C不是B一個子類,你會得到一個編譯錯誤。

+0

不要將指針傳入集合。要麼傳遞一個引用,從而表明你沒有獲得所有權(然後將其轉換爲存儲在bs中的指針)。或者傳遞一個智能指針,指示您正在獲取所有權(由智能指針的類型定義)。 – 2013-04-21 16:48:52

+0

矢量並不是更好。您正在混合所有權語義。定義允許您定義存儲標準的所有權語義。 – 2013-04-21 16:50:11

+0

這正是我想要避免的,因爲我有大量的重複代碼用於每個新的派生。我剛剛發佈了一個例子。我真正的收藏類有點複雜;-) – 2013-04-21 17:01:11