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

为何删除构造函数后仍允许Test object();与Test object{};写法?

为什么构造函数被删除时,Test object();和Test object{};仍能合法编写?

这个问题涉及C++里两个容易混淆的语法细节,咱们拆开来聊:

关于Test object();

这其实是C++里一个经典的语法陷阱——编译器会把它解析成函数声明,而非对象定义:它代表“声明一个名为object的无参函数,返回Test类型对象”。

正因为它是函数声明,所以你尝试执行std::cout << sizeof(object)时会报错:ISO C++禁止对函数类型表达式应用sizeof。这种写法至今未被废弃,完全是出于向后兼容的考虑——早年的C代码里可能大量存在这类函数声明,C标准委员会不敢轻易修改规则,哪怕它很容易让新手踩坑,C++11也没对这个情况做优化修复。

关于Test object3{};

从C++11引入的列表初始化语法{}在这里的行为很特殊:当类的所有构造函数都被删除时,这种写法会直接创建一个空对象实例,不会调用任何构造函数(自然也不会触发构造函数被删除的错误)。

你看到sizeof(object3)输出1,是因为C要求每个对象必须拥有唯一的内存地址,所以空类的大小会被编译器默认设为1。在这个场景下,operator delete根本派不上用场——因为没有构造函数被调用,也就不需要析构或释放内存,这和旧版本C里把构造函数设为私有、禁止用户创建对象的思路非常相似。

代码示例验证

class Test {
    Test() = delete;
    Test(const Test&) = delete;
    Test(Test&&) = delete;
    Test& operator=(const Test&) = delete;
public:
    template<typename T>
    static void func();
private:
    static std::string m_fileName;
};

int main() {
    Test object(); // 被编译器识别为函数声明,而非对象创建
    Test object2;  // 编译失败:构造函数已删除,无法创建对象
    Test object3{};// 编译通过:成功创建空对象实例
    Test object4({});// 编译失败:尝试匹配已删除的默认构造函数
    return 0;
}

这类代码的用途

这种写法常被用来做函数聚合与封装:把相关的静态函数、静态成员变量放在一个类里,既实现了代码的模块化组织,又通过删除构造函数避免用户意外创建类的实例(虽然object3{};这种写法能创建空对象,但一般不会被当作常规用法)。

内容的提问来源于stack exchange,提问作者Narek Aydinyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:50:28