2012-03-27 5 views
0

私の基底クラス、class Fooは、次のコンストラクタ持つテンプレートクラスである「失われた」されています継承テンプレートクラスのメンバーをテストチェーンのコンストラクタで罰金が、その後

//Declarations 
template <class T> 
class Foo 
{ 
public: 
    Foo::Foo(std::string& root); 
    MemberClass obj; 
} 

template <class T> 
Foo<T>::Foo(std::string& root) 
{ 
    MemberClass obj(root); // initialize the member object 
    obj.getRoot(); // Prints the string 
    // ... 
} 

それは子クラス、あるい

template <class T> 
Bar<T>::Bar(std::string& root) 
    : Foo<T>(root) 
{ 
    //... 
} 

template<class T> 
void 
Bar<T>::accessObj() 
{ 
    this->obj.getRoot(); 
    // Prints the empty string 
} 

エラーが発生していない場合でも、予期しない動作が発生します。この場合、getRoot()は空文字列を返します。

{ 
    MemberClass obj(root); 
    std::cout << &obj << std::endl; 
} 

などのようなBarコンストラクタ:

//... 
    : Foo<T>(root) 
{ 
    std::cout << &this->obj << std::endl; 
} 

出力は、メモリ内の2つの異なる場所を与え、完全に吹いている

は、私はそうのようなFooコンストラクタを変更することによって、これをテストしています私の気持ち。これはなぜですか?どうすれば修正できますか?

答えて

0

あなたのコンストラクタは、より良い次のようになります。

template <class T> 
Foo<T>::Foo(std::string& root) 
    : obj(root) // initialize the member object 
{ 
    obj.getRoot(); // Prints the string 
    // ... 
} 

、あなたはFooのコンストラクタで一時的objを構築し、決してすべてであなたのメンバ変数を初期化しない、それを捨てる前に。

GCCを使用している場合は、-Wshadowオプションを使用するとこの間違いを犯す可能性があります。

+0

私はお詫び申し上げます。私は宣言にそれを含めておくべきです、MemberClass objはそこにインターフェイスの一部として含まれています。 –

+0

私はあなたの宣言があなたが投稿したものからどのように見えると思いました。私の答えは正しいと思いますか? –

+0

"obj"がクラスのメンバである場合、Fooのインスタンス生成後にどのように破棄されますか? (私はあなたの答えをテストしていますが、夕食を料理しています:-)) –

関連する問題