重载operator new运算符——此代码难道不应报错吗?
关于operator new重载与
new Dummy()调用的清晰解释 嘿,我来帮你把这个逻辑理清楚,你之前的理解有个关键误区,咱们一步步拆解:
核心误解纠正
首先明确:new Dummy()并不会把Dummy类型隐式转换成size_t,编译器的处理逻辑比这个要清晰得多。
当你写new Dummy()时,编译器做了两件事
- 第一步:自动计算
Dummy类型的内存大小(也就是sizeof(Dummy)),把这个值作为size_t参数,调用你重载的operator new函数。这一步完全是编译器自动完成的,不需要你手动传递,也不存在类型转换的问题。 - 第二步:在
operator new分配好的内存空间上,调用Dummy的默认构造函数——这里的()就是用来触发构造函数初始化对象的,它和operator new的参数没有任何关系。
为什么不会报错?
这个两步式的流程是C++标准明确规定的,只要你的operator new重载符合标准签名(比如void* operator new(size_t size)),编译器就会自动完成这两步的衔接,完全是合法的语法。
举个直观的代码例子验证:
#include <iostream> #include <cstdlib> class Dummy { public: Dummy() { std::cout << "Dummy 构造函数被调用\n"; } }; // 重载全局operator new void* operator new(size_t size) { std::cout << "operator new 被调用,传入大小: " << size << "\n"; return malloc(size); } void operator delete(void* ptr) { free(ptr); } int main() { Dummy* p = new Dummy(); delete p; return 0; }
运行后会输出类似这样的结果(空类Dummy的大小至少为1):
operator new 被调用,传入大小: 1
Dummy 构造函数被调用
你能清楚看到:先调用operator new传入类型大小,再执行构造函数初始化对象。
额外提醒
如果你的operator new重载签名不符合标准(比如参数不是size_t),那编译器才会报错无法匹配;但只要遵循标准签名,new Dummy()的调用就会被正确解析。
内容的提问来源于stack exchange,提问作者MistyD
相关产品推荐
相关产品推荐

