`new` 运算符是否总是调用构造函数?

Does the `new` operator always call the constructor?

我的问题受到了 Thomas Cormen 教授对他 Quora answer$.

second comment 的影响

他说构造函数执行以下三个任务:

  1. Allocates memory for the object.

  2. Initializes the instance variables of the object, e.g., by implicitly calling init in Python. (I also emphasize that the init method should initialize not some, but all of the instance variables.)

  3. Returns a reference to (i.e., address of) the object.

但是,C++ 的 MSDN documentation* 表示是 new 运算符执行此操作:

Allocates memory for an object or array of objects of type-name from the free store and returns a suitably typed, nonzero pointer to the object.

我的问题是,谁是对的?或者,是否还有更多内容,也许像 new 运算符总是调用构造函数,正如 post?

上的评论所建议的那样

谢谢。

$ 不幸的是,Quora 没有复制 link 评论的选项 - 我只能这样做才能得到答案。
* 虽然我说的是 C++,但我认为其他语言也是如此,例如 Java 和 C#(虽然我不是 100% 确定)。

如有疑问,请阅读规范。来自 en.cppreference.com

The new expression attempts to allocate storage and then attempts to construct and initialize either a single unnamed object, or an unnamed array of objects in the allocated storage. The new-expression returns a prvalue pointer to the constructed object or, if an array of objects was constructed, a pointer to the initial element of the array.

如果您在链接的 MSDN 页面上搜索 constructor,它是这样的:

When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.

换句话说,如果存在构造函数,则调用构造函数。如果 none 存在,则调用 none。

构造函数不分配内存。 new 分配内存,然后调用适当的构造函数。

这里是半伪代码:

template <typename T>
T* new(Args... arguments_to_constructor_of_T_if_any)
{
    void* mem = malloc(sizeof(T)); // Allocate memory 

    // Call constructor 
    // Compiler will produce machine code to construct object T over memory mem.
    (mem) T(arguments_to_constructor_of_T_if_any); 

    return (T*)(mem);
}

一个例子:

class A
{
   int a;
   int b;

   A(int a, int b) { this->a = a; this->b = b; };
}

int main() 
{
   A* a = new A(3, 4);

   // After compiled, code above will look like : 
   void* mem = malloc(sizeof(A));

   // Below is A(int, int) constructor
   ((T*) mem)-> a = 3;
   ((T*) mem)-> b = 4;
}