为何删除构造函数后仍允许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
相关产品推荐
相关产品推荐

