【问题标题】:The relation between Forward declaration and destructors前向声明与析构函数的关系
【发布时间】:2013-07-28 18:40:25
【问题描述】:

我有以下代码:

#include <iostream>
using namespace std;

class CForward;

void func(CForward* frw) { delete frw; }

class CForward
{
public:
    ~CForward() { cout << "Forward" << endl; }
};

int main()
{
    func(new CForward);
    cin.get();
}

我运行了这个程序,它什么也没打印出来。

为什么?

在main中,我创建了new CFoward,在func中我删除了它并称之为析构函数。

似乎没有调用析构函数。为什么?这与前向减速有关吗?

【问题讨论】:

  • g++ 实际上会告诉你编译这段代码时发生了什么。
  • 至少提高编译器的警告级别。这应该始终发出“删除指向不完整类型的指针”诊断信息。
  • GCC 很有帮助:warning: possible problem detected in invocation of delete operator: [enabled by default] ‘frw’ has incomplete type [enabled by default] forward declaration of ‘class CForward’ [enabled by default] note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.

标签: c++ forward-declaration


【解决方案1】:

确实,您的前向声明引入了一个不完整的类型,该类型后来使用非平凡的析构函数定义,并且不能在删除表达式中使用:

来自 n3337,第 5.3.5/5 段:

5 如果正在删除的对象在删除点具有不完整的类类型,并且完整的类具有 非平凡的析构函数或释放函数,行为未定义。

【讨论】:

  • @user1798362:如果你定义了你的类析构函数(而不是仅仅使用编译器生成的析构函数),这是不平凡的。递归地,如果您的类有任何具有非平凡析构函数的成员,则您的类具有非平凡析构函数。所有其他析构函数都是微不足道的(它们实际上什么都不做)。
【解决方案2】:

是的。实际上在函数func中,编译器并不知道cForward的完整类型。所以不需要调用析构函数。

如果你把函数放在类之后,它就可以正常工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 2018-08-29
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多