2011-09-15 79 views
3

我在設計實現中遇到一些問題時遇到了問題。它是這樣的:從模板C++正向聲明派生類

我有一個模板基類有一個轉換方法。

// Foo.h 

class Bar; 

template<typename T> 
class Foo { 

    virtual const Bar toBar(); 

} 

我想要一個派生類欄以從富的例如具體形式繼承:

// Bar.h 
class Bar : public Foo<float> { 
    // Insert Bar methods here, Etc. 
} 

爲Foo是一個模板的實現必須在頭完全確定,這將導致問題是方法toBar()的實現需要能夠創建Bar類型的實例。所以這告訴我需要在Foo定義之後但在Foo實現之前包含Bar.h頭文件。

但是,在Bar.h中,類Bar是從Foo派生的,因此必須提供Foo的完整定義。這會導致問題,因爲這兩個文件具有無法通過前向聲明解決的循環依賴性,因爲前向聲明是派生類。

這得到更復雜如果另一類SomeClass的具有類型欄的數據成員,因爲這需要包括Bar.h其包括foo.h中哪個(因爲它是一個模板) 包括Bar.h.

哦,只是要清除所有的頭文件都包含衛士使用

#ifndef _HEADER_NAME_H_ 
#define _HEADER_NAME_H_ 
... 
#endif 

怎麼會有其他人來解決這樣複雜的問題?

作爲更具體的例子說我有一個具有將它轉換爲人類可讀String類如toString(的方法的Array類)...然而String類被聲明爲作爲

class String : public Array<char> {...}; 

在此先感謝。 Gary。

+0

也許使用指針,而不是實例本身,作爲返回值? – Griwes

+0

模板中有虛擬的東西有臭味。看起來好像兩個不同的想法被混合在一起(多態與專業化)。 – Skizz

+0

@Skizz派生類有能力擴展和覆蓋。也許我可以使用sspecialisation和typedef來代替? EG: typedef Array String; template <> class Array {String toSting();/*字符串特定的專業化方法(如修剪等* /} –

回答

1

爲了使Foo<float>成爲一個基類,它必須已經完全由定義點Bar定義。然而,Foo並不一定需要知道約Bar,如果您可以使Bar成爲Foo中的相關類型名稱。

在定義Foo之前的Bar的前向聲明可能就足夠了。如果你發佈/鏈接更具體的代碼,我可能會給你一個更好的答案。

試試這個:

class Bar; 

template< typename T, typename DependantBar = Bar > 
class Foo { 

    virtual const DependantBar toBar(); 

} 
0
class Bar : public Foo<float> { 
    template <typename T> 
    Bar create(const Foo<T>&); 
}