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<>Counter 都会打印只有当我创建CountedInstances注释中的类型对象时才会发生的情况。这是为什么?

4

1 回答 1

1

来自IBM C++ 编译器参考(重点是我的):

如果编译器隐式实例化包含静态成员的类模板,则这些静态成员不会被隐式实例化只有当编译器需要静态成员的定义时,编译器才会实例化静态成员。

因此,要强制编译器有效地实例化GenTest<int>::OnePerTypeand GenTest<double>::OnePerType,您必须以某种方式引用它们。例如,您可以(void)&OnePerType;在构造函数中添加(现场示例:http: //ideone.com/CWNr7U)。


编辑:感谢chris.schuette,这里引用了 C++ 标准(检查 N3337)第 14.7.1 节(强调我的):

1 (...) 类模板特化的隐式实例化导致类成员函数、成员类、作用域成员枚举、静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化; (...)

8 类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化

于 2013-06-16T11:03:22.593 回答