2011-09-15 10 views
3

デザインの実装で何らかの不具合が発生しています。これは次のようなものです:forwardはテンプレートC++の派生クラスを宣言します

私は変換方法を持つテンプレートの基本クラスを持っています。

// Foo.h 

class Bar; 

template<typename T> 
class Foo { 

    virtual const Bar toBar(); 

} 

Iは、派生クラスのバーは、例えば、フーの特定の形態を継承する:

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

fooが実装が完全ヘッダに定義されなければならないテンプレートであるように、これは、原因toBar()メソッドの実装でBar型のインスタンスを作成できる必要があるという問題があります。だから、Fooの定義の後でFooの実装の前にBar.hヘッダファイルをインクルードする必要があることがわかります。

しかしBar.hではBarクラスはFooから派生しているため、Fooの完全な定義を提供する必要があります。これは、前方宣言が派生クラスであるため、2つのファイルが循環宣言を介して解決できない循環依存性を持つため、問題を引き起こします。

別のクラスSomeClassに、Bar.hを含むBar.hを含むBar型のデータメンバがある場合、これはさらに複雑になります。これは(テンプレートであるため) にBar.hが含まれています。

ああ、ちょうど明確にするために、すべてのヘッダファイルは、他の人がこのような複雑な問題を解決した方法

#ifndef _HEADER_NAME_H_ 
#define _HEADER_NAME_H_ 
... 
#endif 

を使用して包含ガードを持っていますか?より具体的な例として

は、私は、このようなのtoString()のように人間が読めるStringクラスに変換する方法を持っているArrayクラスを持っていると言う...しかし、Stringクラスは

class String : public Array<char> {...}; 
ようであるとして宣言されています

ありがとうございます。 ゲーリー。

+0

たぶん、戻り値としてポインタ、インスタンスではなく自分自身を、でしょうか? – Griwes

+0

テンプレートにはバーチャルなことがあります。それは、2つの異なるアイデアが一緒にマッシュされているように思えます(多型と特殊化)。 – Skizz

+0

@Skizz派生したクラスは、拡張したり上書きすることができるようになっています。たぶん私はsspecialisationとtypedefを代わりに使うことができますか? EG: typedef配列文字列; テンプレート<> クラス {String toSting(); –

答えて

1

Foo<float>を基本クラスにするには、Barの定義で完全に定義されていなければなりません。ただし、Fooは、Barについて知る必要はありません。BarFooの従属型名にすることができます。

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>&); 
} 
関連する問題