You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何默认/删除构造函数场景下析构函数未调用?关于()的疑问

为什么Bar b();和Foo f();不会调用析构函数?

这绝对是C里最容易踩坑的语法陷阱之一——咱们俗称的「最令人困惑的语法解析(Most Vexing Parse)」,我当初刚学C的时候也栽过好几次!

核心原因:它们不是对象定义,是函数声明!

当你写下Bar b();或者Foo f();时,编译器不会把它们解析为创建无参对象的代码,而是会优先按照函数声明来处理:

  • Bar b(); 等价于:声明一个名为b的函数,该函数没有参数,返回值是Bar类型
  • Foo f(); 等价于:声明一个名为f的函数,该函数没有参数,返回值是Foo类型

既然根本没有创建任何对象,自然不会调用构造函数初始化对象,程序结束时也没有需要销毁的对象,所以析构函数完全不会被触发。

对比其他写法的差异

  • (C) Foo f;:这是标准的对象定义语法,编译器明确知道你要创建一个Foo类型的对象f,会调用默认构造函数初始化它。当程序生命周期结束(比如main函数返回)时,对象被销毁,析构函数也就被调用了。
  • (D) Bar b;:你尝试直接定义Bar对象,但Bar的默认构造函数被=delete禁用了,编译器会直接报错,提示你无法使用已删除的构造函数。

如何避免这种歧义?

在C++11及之后的版本中,可以使用列表初始化语法来明确创建无参对象,比如:

Foo f{}; // 明确是对象定义,不会被解析为函数声明
Bar b{}; // 同样是对象定义尝试,但会因为构造函数被delete报错

这种写法可以彻底避免编译器把对象定义误判为函数声明的问题。

内容的提问来源于stack exchange,提问作者Joseph D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:32:35