为什么在 C++ 中有这么多不同的方式使用 new 运算符?
我刚刚阅读了cplusplus.com 上的新运算符说明。该页面给出了一个示例来演示使用 new 运算符的四种不同方法,如下所示:
// operator new example
#include <iostream>
#include <new>
using namespace std;
struct myclass {myclass() {cout <<"myclass constructed\n";}};
int main () {
int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));
int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);
myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)
new (p3) myclass; // calls constructor
// same as:
// operator new (sizeof(myclass),p3)
return 0;
}
我的问题是:
- 使用的最佳实践是什么 新运营商?
myclass* p3 = new myclass
是否等同于myclass* p3 = new myclass()
?
I've just read the new operator explanation on the cplusplus.com. The page gives an example to demonstrate four different ways of using new operator as following:
// operator new example
#include <iostream>
#include <new>
using namespace std;
struct myclass {myclass() {cout <<"myclass constructed\n";}};
int main () {
int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));
int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);
myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)
new (p3) myclass; // calls constructor
// same as:
// operator new (sizeof(myclass),p3)
return 0;
}
My questions are:
- What is the best practice of using
new operator? - Is
myclass* p3 = new myclass
equivalent tomyclass* p3 = new myclass()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
因为他们有不同的目的。如果您不希望
new
在失败时抛出std::bad_alloc
,则可以使用nothrot
。如果您想在现有存储中分配对象,您可以使用placement new……如果您想要原始的、未初始化的内存,您可以直接调用operator new
并将结果转换为目标类型。在 99% 的情况下,
new
的简单标准用法是MyClass* c = new MyClass()
;对于你的第二个问题:< code>new Object() 与
new Object
形式通常并不相同。请参阅此问题和回复 详细信息。但这确实是吹毛求疵。通常它们是等效的,但为了安全起见,总是选择new Object()
;请注意,在这个特定的示例中,它们是相等的,因为MyClass
没有任何成员,所以严格来说,您的问题的答案是肯定的。Because they have different purposes. If you didn't want
new
to throwstd::bad_alloc
on failure, you would usenothrow
. If you wanted to allocate your objects in existing storage, you would use placement new … if you want raw, uninitialized memory, you would invokeoperator new
directly and cast the result to the target type.The plain standard usage of
new
in 99% of all cases isMyClass* c = new MyClass()
;To your second question: the
new Object()
vs.new Object
forms are not generally equal. See this question and the responses for the details. But that really is nitpicking. Usually they are equivalent, but to be on the safe side always picknew Object()
; Note that, in this particular sample they are equal becauseMyClass
doesn't have any members, so strictly speaking the answer to your question is yes.1) 其中一些仅在特定的、不寻常的情况下使用。无论如何,大多数时候,普通的传统传统方式是最好的:
2)是的,它们是。如果构造函数没有参数,则括号是可选的。如果你声明一个自动变量——也就是说,
你必须省略括号,否则它就是一个函数声明!因此,许多人会告诉您在 new 表达式中也省略它们。我认为这是一个很好的做法,但我只是习惯了将它们包括在内。
1) Several of these are used only in specific, unusual situations. The plain old traditional one is best, most of the time anyway:
2) Yes, they are. If the constructor has no arguments, the parentheses are optional. If you're declaring an automatic variable -- i.e.,
then you must omit the parentheses, or it's a function declaration! As a result, many people will tell you to omit them in the
new
expression as well. That's a good practice, I think, but I'm just used to including them.您在不同的情况下需要它们,而不是“最佳实践”。例如,大多数人只想调用 new x() 来分配一些内存并创建对象。但是,有时您不希望在
new
失败时引发异常,因此您可以调用new (nothrot)
来获取 null 返回。如果您已经分配了一些内存但需要创建对象,则可以通过调用 new (p3) x 来使用“placement new”。
在极少数情况下,您需要使用类的内存分配器但实际上并不创建对象,您可以使用
(myclass*) operator new (sizeof(myclass))
语法。Rather than "best practice", you need them in different situations. For example, most people just want to call
new x()
to allocate some memory and create the object. However, sometimes you're in situations where you don't want an exception thrown in casenew
fails, so you callnew (nothrow)
instead to get a null back.If you already have some memory allocated but need to create an object, you use "placement new" by calling
new (p3) x
.In the rare case where you need to use a class's memory allocator but not actually create an object, you use the
(myclass*) operator new (sizeof(myclass))
syntax.以下是我的建议:
new
;路过可以的时候参考一下。 (避免内存泄漏)。
operator new
:x = new X(); // 记住使用delete
std::vector
而不是数组new
:x = new X()[数量]; // 记得使用delete[]
new
除非你绝对知道原因。
一般来说,placement new 用于从特定地址或特殊内存池进行分配。这是一个高级主题。
Here are my recommendations:
new
; pass byreference when possible. (Avoids memory leaks).
operator new
:x = new X(); // Remember to use delete
std::vector
to arraynew
:x = new X()[quantity]; // Remember to use delete []
new
unlessyou absolutely know the reasons.
In general, placement new is used to allocate from specific addresses or a special memory pool. This is an advanced topic.