2014-03-04 93 views
3

請看下面的例子如何獲得派生類的子類型在基類中

template <typename T> 
class A 
{ 
     typename T::x a;   //not used 
     virtual typename T::x* function()=0; 
}; 

class B:public A<B> 
{ 
public: 
     typedef XXX x; 
     x obj; 
     x* function() 
     { 
      return &obj; 
     } 

}; 

在這裏,我想使用的類型B::xA類。

有沒有辦法做到這一點?

+0

你不這樣做嗎? – Paranaix

+0

獲取錯誤'無效使用未定義類型'B類' – rajenpandit

+1

是不是這個問題非常類似於討論[這裏](http://stackoverflow.com/q/17478621/420683)? – dyp

回答

5

這不起作用。爲了實例化A,編譯器需要至少有一個前向聲明x。但是你不能轉發declare類型的成員,因爲這是類型的實現細節,並且意味着你已經知道了關於類的一些部分。

你可以,不過,要返回類型通過直接A,並以此作爲返回類型:

template <typename T> 
class A 
{ 
public: 
    typedef T ret_type; 
    virtual ret_type* function() = 0; 
}; 

class B : public A<int> 
{ 
public: 
    A::ret_type obj; 
    virtual A::ret_type* function() override 
    { 
     return &obj; 
    } 
}; 

通過這種方法,你可以這樣做:

class X : public A<int> { ... }; 
class Y : public A<int> { ... }; 

A<int>* p1 = new X(); 
A<int>* p2 = new Y(); 
p1->function(); 
p2->function(); 

.. 。使基類更有用。

父母不需要知道任何關於孩子的事情,否則繼承變得毫無意義。在你的情況下,A可以被認爲是一個接口,任何實現接口A<int>的類將表現相同。相反,如果您將子級傳遞給A,則每個接口實現都是不同且唯一的,即使它可能具有完全相同的返回類型。如果你真的需要這個,可以考慮將A作爲一個實用類並作爲成員嵌入到子類中(「支持繼承的組合」)。

+1

感謝您的建議,我想我可以通過使用這個概念來實現願望結果。 – rajenpandit