2017-05-24 9 views
-1

私は抽象クラスPrimitiveを持っています。抽象クラスにはいくつかの純粋な抽象関数があります。抽象基本クラスのテンプレートインスタンス化を作成するにはどうすればよいですか?

それから私は、テンプレートとツリーの実装を持っている:

このコードで

PrimitiveTree<Primitive> *ptree; 

として別のファイルに使用されている

template<typename PrimitiveT> 
class PrimitiveTree { 
    ... 
} 
// explicit instantiation 
template class PrimitiveTree<Project::Primitive>; // abstract 
template class PrimitiveTree<SimpleTrianglePrimitive>; // implementation 

私はerror C2259: 'Project::Primitive': cannot instantiate abstract classを取得します。抽象クラスのインスタンスを削除すると、PrimitiveTree<Primitive>の対応するシンボルがオブジェクトファイル内に見つからないというリンカエラーが発生します。

Primitiveをテンプレート引数として使用すると、ヘッダーファイル内のメソッドと同様のクラスにはこれらの問題はありません。

テンプレート引数が抽象クラスであっても、必要なシンボルがオブジェクトファイルに追加されるように、テンプレートクラスをインスタンス化する必要はありますか?

+1

一般に、動的多型をテンプレートと組み合わせることは悪い考えです。考え直してください。 – KonstantinL

+1

[MVCE](https://stackoverflow.com/help/mcve)を入力してください。テンプレートパラメータ 'PrimitiveT'が(プリミティブ化された)クラステンプレート' PrimitiveTree'によってどのように使われているかははっきりしていません。 – Walter

+0

@Walter [mcve] –

答えて

1

テンプレートPrimitiveTree<PrimitiveT>は、PrimitiveT(テンプレートパラメータ)がインスタンス化可能であること、つまり抽象ではないことを保証する必要があります。抽象クラスの1つのプロパティは、インスタンス化できないということです。

これは、PrimitiveTreeテンプレートがポインタまたはPrimitiveTへの参照でのみ機能し、実際のインスタンスPrimitiveTを決してインスタンス化しないことを意味します。つまり、PrimitiveTをデータメンバー(静的または非静的)として宣言することはできません。値でPrimitiveTを渡すことはできません。 new表現がインスタンス化可能な(すなわち抽象的でない)タイプに依存しているため、new式(たとえばsome_pointer = new PrimitiveT[5])を持つインスタンスを動的に作成することもできません。

どこでもPrimitiveTが使用されるところは、参照またはポインタのいずれかでなければなりません。ポインタまたは参照をPrimitiveTに定義または宣言するか、関数/引数として参照/ポインタを渡しても、PrimitiveTがインスタンス化可能であるとは限りません。

PrimitiveTreeに対応するコードをPrimitiveTに基づいて記述すると、実装ではテンプレートをインスタンス化できません。

別のヘッダーファイルの「類似クラス」はおそらくPrimitiveが上記のようなガイドラインに従うため、インスタンス化可能であるとは限りません。

+0

のための魔法のタグ '[mcve]'があります。これで問題は解決しました。 – allo

関連する問題