重写operator new后无法使用placement new?相关技术疑问
自定义类operator new后placement new编译错误的原因与解决办法
问题原因
当类中自定义了operator new(std::size_t)成员函数时,C++的名字查找规则会优先在类作用域内匹配operator new重载。标准库提供的placement new(void* operator new(std::size_t, void*))属于全局作用域,此时会被类自定义的版本隐藏,编译器无法找到匹配的placement重载,因此触发"no matching function for call to 'Base::operator new(sizetype, void*)'"错误。
解决办法
有两种直接有效的修复方式:
方法一:显式调用全局placement new
在new关键字前添加::,强制编译器使用全局作用域的placement new版本:
Base* b2 = ::new ((void*)buff) Base;
方法二:在类中引入全局operator new重载
在Base类的public区域添加using std::operator new;,将全局所有operator new重载(包括placement版本)引入类作用域,让编译器能找到匹配的重载:
class Base { public: char c = 'a'; int i = 42; void* operator new(std::size_t size) { std::cout << "Base::new()" << std::endl; std::cout << "param size: " << size << std::endl; return malloc(size); } // 引入全局operator new重载 using std::operator new; };
效果验证
两种方法都能保留自定义operator new(std::size_t)的行为,同时让placement new正常执行。执行后,buff数组会正确初始化Base的成员变量,后续输出buff[0]会得到'a',*((int*)&buff[4])会得到42。
内容的提问来源于stack exchange,提问作者Alightor Li
相关产品推荐
相关产品推荐

