首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我仍然不相信在没有对象“构造”的情况下调用“`destructor`”

我仍然不相信在没有对象“构造”的情况下调用“`destructor`”
EN

Stack Overflow用户
提问于 2011-11-13 11:20:14
回答 2查看 253关注 0票数 0

案例1

这是基于昨天发布的另一个我的问题,我不情愿地接受了这一消息,可以用以下代码进行总结:

代码语言:javascript
复制
{
    ...
    goto Label;
    A a;
    ...
    Label:DoSomething();
}

其中A是具有定义的constructor和默认destructor的任何类。DoSomething()不使用a。据我所知(我仍在努力处理C++基本构造),在这种情况下不会调用A的析构函数,因为对象a甚至没有构造。

请注意,VS2008编译器给出的警告(C4533 : initialization of 'a' is skipped by 'goto Label')不是错误,除非您试图为A定义一个destructor,当编译器神秘地将警告更改为错误(C2362 : initialization of 'a' is skipped by 'goto Label')时,似乎是为了阻止某人探究这个问题,顺便说一句,这让我想起了本质上的量子现象。

案例2

这是constructor抛出异常的正常情况,在这种情况下,不调用destructor,正如讨论的这里这里

因此

Case1中,没有调用constructor,但是调用destructor是为了销毁未创建的东西,对我来说这似乎很奇怪。在Case2中,调用构造函数,抛出异常,不调用destructor,这在我看来是合理的。

我认为这两个例子值得进一步澄清。

编辑

Case2中,编译器可能使用标志来避免破坏由于抛出而非构造的对象。为什么不能在Case1中使用这些相同的标志来标识由于goto而没有构造的对象?

EN

回答 2

Stack Overflow用户

发布于 2011-11-13 11:27:18

在C++中,跨越变量初始化(构造函数调用)的gotos正是因为这个原因而被禁止的: goto跳过构造函数调用。在goto和对DoSomething的调用之后,变量a将超出作用域,因此将在a上调用析构函数,因为goto跳过构造函数调用而没有构造析构函数。

VS2008在这里是宽容的,允许当自动生成的析构函数(可能在POD上)没有影响时违反标准。

票数 4
EN

Stack Overflow用户

发布于 2011-11-13 11:30:47

实际上,案例1是无效的C++。编译器必须为此发出诊断,并且允许根本不编译它。如果编译器无论如何都会编译它,那么它将完全取决于编译器如何处理它。在这种情况下,不销毁对象是明智的,但是这需要额外的机器,这意味着不需要为正确的程序设置开销(程序需要检查内部标志是否已经构造了该对象)。我不认为总是可以在编译时解决该检查是否需要,因为这很可能等同于停止问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8111163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档