2010-04-21 76 views
2

我實現了引用計數指針(在本例中被稱爲SP),我遇到了多態性問題,我認爲我不應該這樣做。智能指針和多態性

在下面的代碼:從BaseClass

SP<BaseClass> foo() 
    { 
     // Some logic... 
     SP<DerivedClass> retPtr = new DerivedClass(); 
     return retPtr; 
    } 

DerivedClass繼承。使用普通的指針這應該已經工作了,但用智能指針它說"cannot convert from 'SP<T>' to 'const SP<T>&",我認爲它指的是智能指針的複製構造函數。

如何讓這種多態與引用計數指針? 我很欣賞代碼示例,因爲如果我遇到這個問題,顯然我會在這裏做一些錯誤。

PS:請不要告訴我使用智能指針的標準庫,因爲這是不可能的。

+0

請發佈複製構造函數的代碼。 – Danvil 2010-04-21 11:53:14

+0

在閱讀模板錯誤消息時,注意每個位置中「T」的含義非常重要。該錯誤可能表示類似無法將[SP = ]與[T = DerivedClass]轉換爲常量SP ,並且[T = BaseClass]'表示額外信息是解決方案的一半。 – 2010-04-21 18:38:00

回答

6

相當明顯:

SP<DerivedClass> retPtr = new DerivedClass(); 

應該是:

SP<BaseClass> retPtr = new DerivedClass(); 
+2

將SP 轉換爲SP 對於良好的智能指針實現應該沒有問題。 – Danvil 2010-04-21 11:54:23

+0

這解決了'foo()'中的特定問題,但它並不適用於可能需要轉換的其他地方的自然語法。 – Gorpik 2010-04-21 12:02:48

+1

@Danvil:轉換不是問題,除非在有限的情況下(協變引用和指針),否則不能更改重載函數的返回類型,因此甚至無法創建錯誤類型的「SP」也沒有意義。這個答案最簡單:創建一個實際返回類型的對象。 – 2010-04-21 12:04:13

0

爲什麼不加模板賦值運算符:

template <class Base> 
class SP 
{ 
    ... 

    template<class Derived> 
    operator = (SP<Derived>& rhs) 
    { 
     ... 

(也許拷貝構造函數,太)?

4

您應該添加的隱式轉換構造函數SP<T>

template<class T> 
struct SP { 
    /// ...... 
    template<class Y> 
    SP(SP <Y> const & r) 
    : px(r.px) // ... 
    { 
    } 

    //.... 
private: 
    T * px; 
} 
+0

模板構造函數絕不是複製構造函數。複製構造函數不會幫助;這是一個非顯式的轉換構造函數。 – 2010-04-21 12:17:35

+0

@Charles。對。不管。 – 2010-04-21 12:24:03

0

除了拷貝構造函數:

SP(const SP<T>& ref); 

你需要一個轉換構造函數:

template<typename T2> 
SP(const SP<T2>& ref); 

否則,編譯器將不知道如何構造SP<BaseClass>SP<DerivedClass>;對他而言,他們是無關的。

轉換構造函數相當簡單,因爲在內部您可以自動將*DerivedClass轉換爲*BaseClass。代碼可能非常類似於複製構造函數。