自动销毁静态对象

Automatic destruction of static object

本文关键字:静态 对象      更新时间:2023-10-16

为什么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是模板类型的成员有关,但这就是我所得到的

我发现§14.7.1隐式实例化

1/[…类模板专门化的隐式实例化导致声明的隐式实例化,但不导致定义或默认实参、类成员函数、成员类、限定作用域的成员枚举、静态数据成员和成员模板的实例化。[…]

第二个音符:

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

因此,除非你使用它,否则不应该被实例化。这不是优化,只是符合标准[n3092]。

除非使用,否则不会被实例化。

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

同时,修复编译错误:

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

类模板的成员仅在需要时才实例化;在这种情况下,没有任何引用静态成员,因此它没有被实例化,即使类模板本身被实例化。

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