2016-03-26 4 views
0

私は基底クラスclass A<T>とderrivedクラスclass B : public A<string>を持っています。g ++はフィールドの基本コンストラクタを間違えて、それに対するパラメータを無視します

class Aには、唯一のパラメータとして整数をとるコンストラクタと標準コピーコンストラクタがあります。パラメータのないデフォルトのコンストラクタはありません(私が定義したコンストラクタではありません;私はコンパイラが私の問題に関連しているものを作成している可能性があることに気づきます)。

class Bのコンストラクタは次のようになります。

B() 
: A(37) 
{ 

} 

私は取得していたエラーは以下のとおりです。

フィールドの初期化のための基本コンストラクタ呼び出し

fileB.h: In constructor ‘B::B()’: 
fileB.h:25: error: class ‘B’ does not have any field named ‘A’ 

コンパイラのミスや

コンパイラはデフォルト(par ameterless)基底クラスのコンストラクタが呼び出されているものと一致する必要があります...

// Where is it getting this? A() is never written explicitly 
fileB.h:25: error: no matching function for call to ‘A<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::A()’ 
fileA.h:37: note: candidates are: A<T>::A(const A<T>&) [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >] 

...のいずれかを使用して、デフォルト以外のベースクラスのコンストラクタの両方を示唆しています。

// This one matches A(37), right? 
fileA.h:24: note:     A<T>::A(const int&) [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >] 

私は自分のコンピュータ上で私のコードをコンパイルするとき、私はすべてのエラーを取得しないため、このエラーは、私のコンパイラがインストールまたは設定された方法から来ていると信じていますが、私は時に上記のエラーが出るI私の学校のコンピュータにすべてをscpし、コンパイルしてください。私は両方の場所でg ++を使用していますが、明らかにどこかに違いがあります。その違いは何ですか?エラーはどこから来ていますか?

Aからintへの変換演算子は存在しません。また、その逆もありません。

私は両方のシステムでC++ 03を使用しています。

はここでエラーを再現する完全なコードサンプルです(再び、唯一のシステム上):

/******************************* 
* fileA.h 
******************************/ 

template <class T> 
class A 
{ 
    int member; 

    public: 

    A(const int & m) 
     : member(m) 
    { 
    } 

    A(const A & copyFrom) 
    { 
     member = copyFrom.member; 
    } 
}; 


/******************************* 
* fileB.h 
******************************/ 

#include <string> 
#include "fileA.h" 

using namespace std; 

class B : public A<string> 
{ 
    B() 
     : A(37) 
    { 

    } 
}; 
+0

私はそれをどこにしていますか? –

+0

'class B:public class A ' - 'A 'の前に' class'という言葉で実際にコンパイルしましたか? – AnT

+0

Grr。いいえ、申し訳ありません、それは単に 'class B:public A 'です。私は今それを編集します。 –

答えて

1

まず、Aのデフォルトコンストラクタは、コンパイラによって生成されていません。パラメータを持つコンストラクタが少なくとも1つ定義されている場合、デフォルトのコンストラクタは生成されません。

第2に、問題は、BコンストラクタでAのテンプレートパラメータを指定しないという事実に起因します。

A(37)を書くと、コンパイラは存在しないテンプレート化されていないクラスAを探します。

基本クラスは常に構築されます。 Aを構築しないので、コンパイラはデフォルトのコンストラクタを呼び出すためにそれを行います。存在しないので失敗します。

+0

'A (37)'の代わりに 'A(37)'を使用すると、g ++を使用する1つのシステムで完全に動作しますが、g ++を使用する別のシステムでは動作しません。私は 'A 'がより明示的な型指定子だと理解していますが、それはなぜ1つのシステム上でのみ必要なのでしょうか? –

+1

これは動作しません。しかし、それは確かに実装定義されています。あなたの実装の1つは、クラス宣言のA からBを派生させたので、BコンストラクタのA を意味すると推測できます。 – Thomas

+0

「実装定義」とはどういう意味ですか? g ++はg ++ですが、そうではありませんか? –

関連する問題