在以下来自https://docs.microsoft.com/en-in/cpp/cpp/new-and-delete-operators?view=vs-2017的示例中,新运算符在调用中从未传递时,如何知道stAllocateBlock
的值:
Blanks *a5 = new(0xa5) Blanks;
什么是operator new
在全球范围内的实际实施。它如何调用正在创建的特定对象的构造函数以及它采用的参数。
// spec1_the_operator_new_function1.cpp
#include <malloc.h>
#include <memory.h>
class Blanks
{
public:
Blanks(){}
void *operator new( size_t stAllocateBlock, char chInit );
};
void *Blanks::operator new( size_t stAllocateBlock, char chInit )
{
void *pvTemp = malloc( stAllocateBlock );
if( pvTemp != 0 )
memset( pvTemp, chInit, stAllocateBlock );
return pvTemp;
}
// For discrete objects of type Blanks, the global operator new function
// is hidden. Therefore, the following code allocates an object of type
// Blanks and initializes it to 0xa5
int main()
{
Blanks *a5 = new(0xa5) Blanks;
return a5 != 0;
}
与其他运算符不同,其中涉及该运算符的表达式有效地直接映射到相应的operator
函数调用,new-expression不仅仅是调用operator new
函数的一种方式。 new-expression的目的是创建某种类型的对象。创建某种类型的对象不仅仅是简单地决定该对象应该存在哪一块内存。例如,可能必须调用构造函数。 new-expression可以使用allocation function(即operator new
函数)来分配存储空间。但并非每个新表达式都必须调用分配函数。 In some situations,允许编译器省略对分配函数的调用,例如,将多个分配合并为单个分配。所以最后,编译器决定何时为内存分配内存。它调用operator new
函数来处理实际的内存分配。当它这样做时,它知道根据将在该存储中创建哪些对象来请求多少内存。并且它会将请求的大小作为operator new
函数的第一个参数传递。第一个参数总是存在,你在一个新表达式中的new
之后在括号中写的东西将简单地作为参数传递,除了隐含的第一个...
它是根据被分配对象的大小计算出来的。在表达中
Blanks *a5 = new(0xa5) Blanks;
stAllocateBlock
将是sizeof(Blanks)
您在Blanks
中将其命名为new(0xa5) Blanks
。实现至少自动传递sizeof(Blanks)
并不困难。事实上,它正是它所做的。
这也是为什么重载的operator new
与派生类一起正常工作的原因。例如:
struct D : Blanks { char dummy[2]; };
如果你要做new(0xa5) D
,那么实现将传递sizeof(D)
,因为这是静态出现在新表达式中的派生类最多的类。