2012-02-09 10 views
5

C++でいくつかの自己登録クラスを作成しようとしています。だから、私はhereと同じような解決策を試みました。これをやっているうちに、私は何か奇妙なことにつまずく。 main()が開始される前に、すなわち -C++でテンプレートクラスの静的フィールドの初期化

#include <iostream> 

class StaticClassType { 
public: 
    StaticClassType() { 
    // Notify when the static member is created 
    std::cout << "We're in." << std::endl; 
    } 
}; 


template<typename T> 
class TestClass1 { 
public: 
    TestClass1() { &m; } 
private: 
    // Static member in a template class 
    static StaticClassType m; 
}; 

template<typename T> 
StaticClassType TestClass1<T>::m; 


class TestClass2 : public TestClass1<TestClass2> { 
public: 
    TestClass2() { } // required; why? 
}; 


int main() { 
    return 0; 
} 

このコードは、(それによって、印刷コンソールに「我々は、にしている。」)起動時に静的メンバ変数TestClass1::mを作成します。ここでは

コードです。しかし、コードはTestClass2の(空の)コンストラクタを記述した場合にのみ機能します(例のように)。

なぜこのコンストラクタを記述する必要がありますか?コンパイラによって生成されるデフォルトのコンストラクタが同じことをしないのはなぜですか?

この問題はテンプレートクラスでのみ発生します。 TestClass1がテンプレートクラスでない場合、コードはTestClass2の空のコンストラクタを記述せずに動作します。

答えて

2

私は(必要ではないコンストラクタ、なし)でも小さな例を作成しました:

#include <iostream> 

class StaticClassType { 
public: 
    StaticClassType(int v) { 
    // Notify when the static member is created 
    std::cout << "We're in."<<v << std::endl; 
    } 
}; 


template<typename T> 
class TestClass1 { 
protected: 
    // Static member in a template class 
    static StaticClassType m; 
}; 

template<typename T> 
StaticClassType TestClass1<T>::m = StaticClassType(3); 


class TestClass2 : public TestClass1<TestClass2> { 
public: 
    void foo() 
    { 
     (void)m; 
    } 
}; 

int main() { 
    std::cout << "main" << std::endl; 
} 

は、それがどこにも使用されていないので、そうでない場合、コンパイラは、静的変数を削除し、FOO()メソッドが必要であることに注意して。

+0

コンパイラの最適化レベルによっては、fooがどこでも使用されていないため、mをインスタンス化することが保証されているかどうかはわかりません。 –

+0

@TomTannerそれは正しいです。要点は、どこにも使用されていなければコンパイラが自由に削除できることです。 –

+0

そのため、私はTestClass1にコンストラクタを持っていました。しかし、依然として疑問が残っています:空のコンストラクタをTestClass2に追加すると、なぜ動作しますか?コンパイラによって自動的に生成されるものとは何が違うのですか? –

0

私の見解では、「問題」は、「テンプレートワールド」ではコンパイラがクライアントコードで実際に使用されているものだけを生成するということです。ここでは、TestClass2クラスをインスタンス化することはありません。したがって、多くのコードは生成されません。試してみてください:

int main() { 

    TestClass2 instance; 
    return 0; 
} 

それが動作します。

関連する問題