我正在看新操作员的签名。这是:
void* operator new (std::size_t size) throw (std::bad_alloc);
但是当我们使用这个运算符时,我们从不使用强制转换。即
int *arr = new int;
那么,在这种情况下,C ++如何将void*
类型的指针转换为int*
。因为,即使malloc
返回void*
,我们也需要明确使用强制转换。
答案 0 :(得分:41)
operator new
和new
运算符之间的C ++存在非常细微的差别。 (再看一遍......排序很重要!)
函数operator new
是C malloc
函数的C ++模拟。它是一个原始内存分配器,其职责仅仅是生成一块内存块来构造对象。它不会调用任何构造函数,因为这不是它的工作。通常,您不会在C ++代码中看到operator new
直接使用;它看起来有点奇怪。例如:
void* memory = operator new(137); // Allocate at least 137 bytes
new
运算符是一个关键字,负责为对象分配内存并调用其构造函数。这是C ++代码中最常见的。当你写
int* myInt = new int;
您正在使用new运算符来分配新整数。在内部,new
运算符的工作方式大致如下:
operator new
operator delete
释放上述内存,然后传播异常。由于new
运算符和operator new
是分开的,因此可以使用new
关键字构造对象而无需实际分配任何内存。例如,着名的 placement new 允许您在用户提供的内存中的任意内存地址上构建对象。例如:
T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.'
通过定义自定义new
功能来重载operator new
运算符,可以通过这种方式使用new
;您可以指定分配的方式,C ++编译器会将其连接到new
运算符。
如果您感到好奇,delete
关键字的工作方式相同。有一个名为operator delete
的释放函数负责处理内存,还有一个delete
运算符负责调用对象析构函数和释放内存。但是,operator new
和operator delete
可以在这些上下文之外使用,例如代替C malloc
和free
。
答案 1 :(得分:5)
您将new
表达式与operator new()
函数混淆了。编译前者时,编译器会生成对operator new()
函数的调用,并传递足够大小以保存new
表达式中提到的类型,然后返回该类型的指针。