1

C# では、静的メンバーは、この例のようにジェネリック クラスごとに一意です

using System;

//A generic class
public class GenTest<T>
{
  //A static variable - will be created for each type on refraction
  static CountedInstances OnePerType = new CountedInstances();

  //a data member
  private T mT;

  //simple constructor
  public GenTest(T pT)
  {
    mT = pT;
  }
}

//a class
public class CountedInstances
{
  //Static variable - this will be incremented once per instance
  public static int Counter;

  //simple constructor
  public CountedInstances()
  {
    //increase counter by one during object instantiation
    CountedInstances.Counter++;
    Console.WriteLine(Counter);
  }
}

public class staticTest {
  static void Main(string[] args) {
    //main code entry point
    //at the end of execution, CountedInstances{{Not a typo|.}}Counter = 2
    GenTest<int> g1 = new GenTest<int>(1);
    GenTest<int> g11 = new GenTest<int>(11);
    GenTest<int> g111 = new GenTest<int>(111);
    GenTest<double> g2 = new GenTest<double>(1.0);
  }
}

http://en.wikipedia.org/wiki/Generic_programmingから

C++はどうですか?私はそれを自分で確認しようとしましたが、c++ への変換は静的メンバーを無視しているようです。

#include <iostream>
using namespace std;

class CountedInstances {
public:
  static int Counter;
  CountedInstances() {
    Counter++;
    cout << Counter << endl;
  }
};

int CountedInstances::Counter = 0;

template<class T> class GenTest {
  static CountedInstances OnePerType;
  T mT;
public:
  GenTest(T pT) {
    mT = pT;
  }
};

template<class T> CountedInstances GenTest<T>::OnePerType = CountedInstances();

int main() {
  GenTest<int> g1(1);
  GenTest<int> g11(11);
  GenTest<int> g111(111);
  GenTest<double> g2(1.0);
  cout << CountedInstances::Counter << endl;
  //CountedInstances c1;
  //CountedInstances c2;
}

この回答では、c++ の静的メンバーは特殊化ごとに一意であることがわかりますが、私のコードは正当に見えますが、静的メンバーOnePerTypeは無視されます。

コメントのようGenTest<>なタイプのオブジェクトを作成した場合にのみ、各カウンターが出力されると思いました。CountedInstances何故ですか?

4

1 に答える 1

1

IBM C++ コンパイラ リファレンスから(強調は鉱山):

コンパイラが静的メンバーを含むクラス テンプレートを暗黙的にインスタンス化する場合、それらの静的メンバーは暗黙的にインスタンス化されませんコンパイラは、静的メンバーの定義が必要な場合にのみ、静的メンバーをインスタンス化します。

したがって、コンパイラに と を効果的にインスタンス化させるにはGenTest<int>::OnePerTypeGenTest<double>::OnePerType何らかの方法でそれらを参照する必要があります。たとえば(void)&OnePerType;、コンストラクターに追加できます (実際の例: http://ideone.com/CWNr7U )。


編集: chris.schuetteのおかげで、ここに C++ 標準 (N3337 をチェック)、§ 14.7.1 (強調鉱山) からの引用があります:

1 (...) クラス テンプレートの特殊化の暗黙的なインスタンス化により、クラス メンバー関数、メンバー クラス、スコープ メンバー列挙、静的データ メンバー、およびメンバー テンプレートの定義または既定の引数ではなく、宣言の暗黙的なインスタンス化が発生します。 ; (...)

8 クラス テンプレートの暗黙的なインスタンス化によって、そのクラスの静的データ メンバーが暗黙的にインスタンス化されることはありません

于 2013-06-16T11:03:22.593 に答える