我正在尝试使用参数作为全局实现operator new。如果没有args的new重载会没有问题,但是在尝试编译时会出现以下错误
inline void* operator new(size_t, void* p) {
//...
return p;
}
c:\ bjarne_exercise_6.cpp(14):错误C2084:函数'void * operator new(size_t,void *)throw()'已经有一个正文 c:\ program files \ microsoft visual studio 10.0 \ vc \ include \ new(55):参见先前对'new'的定义
c:\ bjarne_exercise_6.cpp(40):错误C2264:'operator new':函数定义或声明中的错误;功能未被称为
我刚刚解决了这个问题,你必须在#include stdafx.h之前声明这个 不,不是真的。它编译得很好,但仍然没有调用此函数,但是来自新头文件的版本。是这样,因为新标题中已经定义了新的(有2个参数)。普通的new(只有1,size_t参数)只在那里声明,所以你仍然可以重载它。因此,如果你想要带有多个参数的特殊new,下面的@trion建议的解决方案是合适的。
答案 0 :(得分:5)
此operator new
的放置形式(标准称之为)已在全局命名空间的C ++程序中定义,您无法自己提供定义。与其他全局operator new
不同,这个不可替换。
答案 1 :(得分:3)
1)您有编译错误,因为全局级别放置新运算符无法被替换!请参阅c ++ 11标准(以前的标准)。
18.6.1.3 Placement forms [new.delete.placement] 1 These functions are reserved, a C++ program may not define functions that
替换了中的版本 标准C ++库(17.6.4)。 (3.7.4)的规定不适用于这些保留的安置形式 operator new和operator delete。 void * operator new(std :: size_t size,void * ptr)noexcept;
所以基本上你可以替换另一个全局新运算符(见下文),但不作为标准的放置形式禁止它!
void* operator new (std::size_t size) throw (std::bad_alloc)
2)另一方面,您可以编写自己的类级别新操作符,包括在您的类中放置新的操作符,这没关系:
class Test
{
public:
void* operator new (std::size_t size) throw (std::bad_alloc) {
return malloc(size);
}
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw() {
return malloc(size);
}
void* operator new (std::size_t size, void* ptr) throw() {
return malloc(size);
}
};
答案 2 :(得分:2)
C ++标准定义了一个展示位置operator new
在标题文件void*
中额外添加<new>
。
它的实现类似于:
void* operator new(size_t, void* m)
{
return m;
}
它通常用于在已分配的内存上实例化对象,例如由STL容器将分配与实例化分开。因此,如果您根据<new>
添加任何标准标头,则已定义新的展示位置。
如果要使用不同的语义创建自己的operator new
版本,可以使用虚拟参数来消除歧义:
struct my_new_dummy {} dummy;
void* operator new(size_t, my_new_dummy, void* m);
//...
int mem;
int* ptr = new(dummy, &mem) int;
编辑:您可以重新定义普通operator new
但不重新定位新的原因是前者默认由编译器定义并且可以手动覆盖,而放置新的在标题中定义,因此导致与重新定义冲突。
答案 3 :(得分:1)
是肯定的。 operator new
的此放置形式已在全局命名空间中定义,因此您无法自己提供定义。这是不可替换的。