2012-09-28 69 views
1

這部分與this SO question有關。如何處理相互依賴且具有模板成員的類?

我有兩個班,他們兩個都是模板,例如:

class Base 
{ 
public: 
    template< class T > void operator=(T other) 
    { 
     //irrelevant 
    } 

    Derived toDerived() 
    { 
     Derived d; 
     //do stuff; 
     return d; 
    } 
}; 

class Derived: public Base 
{ 
public: 
    template< class T > void foo(T other) 
    { 
     //do stuff 
    } 
}; 

正如你所看到的,兩者都模板和Base類函數內我需要創建的Derived一個實例。當然,現在我得到一個錯誤Derived does not name a type。不幸的是,我不能僅僅提前宣佈Derived,因爲它會導致另一個錯誤variable 'Derived d ' has initializer but incomplete type

從上面提到的SO問題我明白,編譯器需要知道所有模板參數能夠正確地轉發聲明它。但顯而易見,我不能僅僅移動Derived聲明,因爲它會導致完全相同的問題,反之亦然。

有沒有辦法做到這一點?

+0

這與模板有什麼關係嗎? – juanchopanza

+2

我認爲它是'Derived'應該有'fromBase'。 – GManNickG

+0

a。你在類定義之後缺少';'。灣我同意GManNickG--你做的不是很好的OOP。 – elyashiv

回答

3
// Declare, but do not define 
class Derived; 

class Base { 
public:  
    // Declare, but do not define 
    // at this point Derived must be declared to be able 
    // to use it in the return type 
    Derived toDerived(); 
}; 

// Define 
class Derived: public Base { 
    // Rest of definition 
}; 

// At this point Derived is defined 

// Define 
Derived Base::toDerived() 
{ 
    // Implementation goes here 
} 
+0

謝謝;)這很簡單,我感到羞恥xD – SingerOfTheFall

+0

如果這全部在標題中,它需要'Base ::'定義前的'inline'關鍵字toDerived'以避免鏈接器錯誤。 –

4

此問題與模板無關。你可以只使用前向申明的Derived編譯的Base::toDerived()申報和移動功能定義 取決於DerivedDerived定義:

// Forward declaration of Derived 
class Derived; 

// Definition of Base 
class Base 
{ 
public: 
    // Base::toDerived() declaration only 
    Derived toDerived(); 
}; 

// Definition of Derived 
class Derived: public Base 
{ 
public: 
... 
}; 

// Base::toDerived() definition 
inline Derived Base::toDerived() 
{ 
    Derived d; 
    // Do dirty things 
    return d; 
} 
3

你可以做

class Derived; 

class Base 
{ 
public: 
    template< class T > void operator=(T other) 
    { 
     //irrelevant 
    } 

    Derived toDerived(); 
}; 

class Derived: public Base 
{ 
public: 
    template< class T > void foo(T other) 
    { 
     //do stuff 
    } 
}; 

Derived Base::toDerived() 
{ 
    Derived d; 
    //do stuff; 
    return d; 
} 

正如你可以看到它與模板無關。

另外,這種設計根本感覺不對。

+0

如果這全部在標題中,它需要'Base :: toDerived'定義前面的'inline'關鍵字來避免鏈接器錯誤。 –

+0

@MarkLakata:好的,我寧願將「inline」放在課堂上的聲明前面。然後它告訴讀者,定義在後面的標題中。也就是說,沒有任何信息表明這是一個標題,在答案中最好不要添加那些不是非常必要的東西(它可以在需要時很容易地添加,但更難以確定刪除它是否安全)。 –