自动销毁静态对象

时间:2011-09-22 13:00:04

标签: c++ templates static-members

为什么C ++不创建/销毁模板类型的静态成员。

请注意以下示例:

#include <iostream>

struct Dump {
  Dump() {
    std::cout << "CTOR" << std::endl;
  }
  ~Dump() {
    std::cout << "DTOR" << std::endl;
  }
};

template <typename T> struct X {
  static Dump dump;
};

template <typename T> Dump X<T>::dump;

struct A : X<A> {
};

int main() {
  A a;
  return 0;
}

我原本以为在执行时我会看到字符串CTOR后跟DTOR。虽然我没有。我在这里缺少什么?

它与dump作为模板类型的成员有关,但这就是我得到的。

3 个答案:

答案 0 :(得分:5)

我在§14.7.1隐式实例化中找到了一些东西。

  

1 / [...]类模板特化的隐式实例化导致声明的隐式实例化,但不是类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板的定义或缺省参数。 [...]

在第二个注释中继续:

  

2 / 除非已明确实例化或明确专门化类模板或成员模板的成员,否则在需要使用特定化的上下文中引用特化时,将隐式实例化成员的特化。成员定义存在;特别是,静态数据成员的初始化(以及任何相关的副作用)除非静态数据成员本身使用,否则不会发生需要定义的方式静态数据成员的存在。

因此,除非您使用它,否则不应该实例化。这不是优化,只是标准[n3092]一致性。

答案 1 :(得分:4)

除非使用,否则不会实例化。这有效:

int main()
{
    A a;
    (void) a.dump;
}

另外,修复编译错误:

template <typename T> Dump X<T>::dump;

答案 2 :(得分:4)

只有在需要时才会实例化类模板的成员;在这种情况下,没有任何东西引用静态成员,所以它没有实例化,即使类模板本身是。

您会发现将语句X<A>::dump;放在某处将导致成员被实例化并创建和销毁对象。