C++ 中的 new 运算符执行以下操作:
分配内存:它在堆上为单个对象或对象数组分配内存。分配的内存量足以容纳指定类型的对象。
初始化对象:分配内存后,new 通过调用对象的构造函数来初始化对象。对于单个对象,它直接调用构造函数。对于对象数组,它为数组中的每个对象调用构造函数。
返回指针:它返回对象类型的指针,该指针指向存储对象的已分配内存的第一个字节。对于数组,它返回指向数组第一个元素的指针。
是否已返回指针,但构造函数尚未完全执行且CPU乱序执行
class Animal {
public:
Animal() {
// Do something for a long time
// xxx
}
};
Animal* test= new Animal;
如果是这样的话,那么使用指针就有问题了
如果您根据 C++ 标准编写具有明确定义行为的 C++ 代码,那么您无需担心指令“乱序”执行。特别是,标准保证在new-expression中,首先调用分配函数,然后,如果分配成功,则初始化对象,并且只有在初始化成功后,new-expression具有一个值,并且该值可以被程序进一步使用。因此,您可以假设您的编译器将生成使程序根据此事件序列运行的代码。
在多线程程序中,C++ 标准提供的保证较弱。多线程程序中的“数据竞争”会导致程序出现未定义的行为,并且观察到的程序行为可能会使指令看起来像是无序执行的,甚至可能会出现更不可预测的结果。而且,即使在没有数据竞争的多线程程序中,也不能保证当线程 A 观察到线程 B 引起的副作用时,线程 A 也能看到线程 B 引起的所有先前副作用,除非进行适当的同步操作被使用。同样,如果您需要特定的行为,则您有责任使用标准提供的同步操作,根据 C++ 标准编写提供该行为的代码。如果你这样做,你就不需要考虑机器层面发生了什么。