【问题标题】:Automatic destruction of static object静态对象的自动销毁
【发布时间】:2011-09-22 13:00:04
【问题描述】:

为什么 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 是模板类型的成员有关,但据我所知。

【问题讨论】:

  • 你在哪里实例化这些类型?
  • 我真的必须这样做吗?反正A是在main中实例化的,我来编辑一下。
  • @VJo:我试图省略对问题不重要的内容。当然我有一个main,看看我的编辑(否则我可以构建一个可执行文件,现在可以吗?)。
  • 嗯。你观察到什么行为?
  • 模板 转储 X::dump;应该是模板 Dump X::dump;

标签: c++ templates static-members


【解决方案1】:

我在 § 14.7.1 隐式实例化中发现了一些内容。

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

第二个音符继续:

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

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

【讨论】:

    【解决方案2】:

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

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

    另外,修复编译错误:

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

    【讨论】:

    • 谢谢,现在它成功了。伙计,这就是我所说的危险行为!
    • 看起来更像是优化
    • 你不需要写(void) a.dump。因为A a 会导致类模板的实例化,这反过来又会创建静态成员实例。
    • @Nawaz:问题的重点是A 没有!至少不是隐含的。我现在所做的是在A::A()中提及该成员。
    • 我被这个咬过一次,我学会了。就这样吧(我查看了标准,但找不到相关段落)
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 2015-01-13
      • 2019-06-30
      • 1970-01-01
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多