3

設計の実装でいくつかの問題を解決するのに苦労しています。次のようになります。

変換メソッドを持つテンプレート基本クラスがあります。

// Foo.h

class Bar;

template<typename T>
class Foo {

    virtual const Bar toBar();

}

たとえば、特定の形式の Foo から継承する派生クラス Bar が必要です。

// 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 型のデータ メンバがある場合、これはさらに複雑になります。これには、(テンプレートであるため) Bar.h を含む Foo.h を含む Bar.h を含める必要があるためです。

ああ、明確にするために、すべてのヘッダーファイルには次を使用したインクルージョンガードがあります

#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
...
#endif

他の人はこのような複雑な問題をどのように解決しましたか?

より具体的な例として、 toString() などの人間が読める String クラスに変換するメソッドを持つ Array クラスがあるとします...ただし、 String クラスは次のように宣言されています

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

前もって感謝します。ゲイリー。

4

2 に答える 2

1

が基底クラスになるためには、定義Foo< float >の時点で完全に定義されている必要がありBarます。ただし、内で依存型名を作成できる場合は、Foo必ずしも について知る必要はありません。BarBarFoo

Bar定義する前の前方宣言でFoo十分かもしれません。より具体的なコードを投稿/リンクすると、より良い答えが得られるかもしれません。

これを試して:

class Bar;

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

    virtual const DependantBar toBar();

}
于 2011-09-15T21:42:40.233 に答える
0
class Bar : public Foo<float> {
    template <typename T>
    Bar create(const Foo<T>&);
}
于 2011-09-15T21:45:08.603 に答える