您好,我正在阅读 C++ 入门书第 5 版的第 19 章。 'Operator new
和 delete
与 new
和 delete
表达式和位置 new
':
AFAIK operator new
和 operator delet
e 分别分配和释放内存,但不在那里构造对象。另一方面,new-表达式
调用operator new
来分配内存,在该内存地址中构造一个对象,最后返回一个指向新分配和初始化的对象的指针。
所以为了理解,我尝试了这个:
struct Foo{
Foo(){std::cout << "Foo()\n";}
~Foo(){std::cout << "~Foo()\n";}
void bar() const{
std::cout << "Foo::bar()\n";
}
};
int main(){
Foo* pf = (Foo*)operator new(sizeof(Foo)); // Foo() is not called! Is it UB?
pf->bar(); // looks to work fine. Does it really?
delete pf; // looks fine?
Foo* pf2 = new Foo{}; // ok Foo() is called
pf2->bar(); // OK
delete pf2; // OK ~Foo() is called
}
正如你在第一个例子中看到的,我直接调用了operator new,我猜后者只分配内存,但不在那里构造对象,最后它返回一个指向void的指针,指向新分配的成员.
所以我没有得到名为 Foo()
的构造函数。现在为什么调用成员函数可以正常工作? pf->bar()
?或者这会产生未定义的行为?
第二个示例 (pf2
) 很简单。
- 如果安全且正确,发生了什么?我如何使用未初始化的对象?谢谢!
最佳答案
除非你使用placement new(这基本上是普通new
的另一半),否则不存在Foo
对象,所以你不能调用成员函数它。而且,如果你确实使用了placement new,你必须自己调用析构函数:
Foo* pf = new (operator new(sizeof(Foo))) Foo; // no cast needed
pf->bar();
pf->~Foo();
operator delete(pf); // analogous, though not equivalent, to std::free
关于c++ - 如果我直接调用operator new而不使用new表达式并将返回指针类型安全地转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67781069/