2017-01-24 3 views
1

私のようなおもちゃのクラス継承している場合:継承を持つテンプレートは、親のコンストラクタを明示的に呼び出すことができますか?

template <typename ModelT> 
class Parent { 
public: 
    Parent(int i) {} 
}; 

template <typename ModelT> 
class Child : public Parent<ModelT> { 
public: 
    Child(int i) : Parent(i) {} 
}; 

int main() { 
    Child<int> c(42); 
} 

がどのように私は明示的にParentParent<ModelT>(i)コンストラクタを呼び出すことができますか?そのまま私は

g++ -std=c++14 ~/tmp.cpp 

とG ++ 5.2.1を起動すると、私は次のエラーを取得する:

/home/rrogers/tmp.cpp: In constructor ‘Child<ModelT>::Child(int)’: 
/home/rrogers/tmp.cpp:9:18: error: class ‘Child<ModelT>’ does not have any field named ‘Parent’ 
    Child(int i) : Parent(i) {} 
       ^
+2

'Parent (i)'と 'main'に' Child'のタイプがありません。 – Jarod42

答えて

3

template <typename ModelT> 
class Parent { 
protected: 
    Parent(int i) {} 
}; 

template <typename ModelT> 
class Child : public Parent<ModelT> { 
public: 
    Child(int i) : Parent<ModelT>(i) {} 
}; 

int main() { 
    Child<int> c(42); 
} 

を試してみてください、あなたのコードを持つ2つの主要な問題がありました。

  1. アクセス指定子。 C++のクラスのデフォルトのアクセス指定子はprivateであるため、ParentコンストラクタはChildクラスには表示されません。私たちがpublicまたはprotectedの指定子をParentに追加すると、class Childはそれにアクセスできます。 Parentクラスのオブジェクトを作成するかどうかを指定していないので、私は注意の面で誤っていて、より制限された保護されたアクセス指定子を使用することをお勧めします。

  2. テンプレートクラス テンプレートクラスのタイプには、テンプレートタイプ指定子が含まれます。 元のコードでは、いくつかの場所が欠落していました。

+0

このコードスニペットは問題を解決するかもしれませんが、[説明を含む](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)は、あなたの質を改善するのに本当に役立ちます役職。将来読者の質問に答えていることを覚えておいてください。そうした人々はあなたのコード提案の理由を知らないかもしれません。 – NathanOliver

+0

私は簡単な説明を加えました。 – ccpgh

4

問題はParentはタイプではなく、クラステンプレートです。

Child(int i) : Parent<ModelT>(i) { } 

の場合:ちょうど正しい基本クラスを提供し、簡単な例については

Child(int i) : Parent<ModelT>(i) {} 
+0

@Slavaどのように? 'Parent'から派生したものは' private'とマークされているので、コンストラクタを呼び出すことはできません。 – NathanOliver

+0

ああ、申し訳ありませんが、あなたは親の会社を意味しています。私はそれがPrivateとして 'Child'によって継承された' Parent'に関するものだと思っていました。とにかくOPが彼の質問を変えたので、それを削除することができます。 – Slava

+0

@スラバ質問に修正が加えられたので、それをすべて吹き飛ばしてください。 – NathanOliver

2

:それはのような実際のクラス型を吐き出すためにそれを使用するためには、順番にテンプレートを指定する必要がありますベースがタイプするには複雑すぎる場合は、親の注入されたクラス名を使用できます。それがあります。それは、修飾されていない名前のルックアップが依存する基本クラスでは見えないことです。しかし、あなたはそれを修飾することができます:

Child(int i) : Child::Parent(i) { } 
       ~~~~~~~ 
+0

コンストラクタはプライベートであってはいけません。 – Cameron

関連する問題