C++ 创建对新对象的引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4863324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create reference to new object
提问by Dan Nestor
I am just learning C++, and I've come across the following conundrum:
我只是在学习 C++,我遇到了以下难题:
As a C++ newbie, I've read that using reference instead of pointers (when possible) is generally a good idea, so I'm trying to get into the habit early. As a result, I have a lot of methods which have the general form of
作为一个 C++ 新手,我读到使用引用而不是指针(如果可能)通常是一个好主意,所以我试图尽早养成这个习惯。结果,我有很多方法,它们的一般形式为
void myMethod(ParamClass const& param);
Now, I'm wondering what is the best way to call these methods. Of course, each call will need a different object passed as a parameter, and as far as I know the only way to create it is the new operator, so now I'm doing the following:
现在,我想知道调用这些方法的最佳方式是什么。当然,每次调用都需要一个不同的对象作为参数传递,据我所知,创建它的唯一方法是 new 运算符,所以现在我正在执行以下操作:
myObject.myMethod(*new ParamClass(...));
While this method totally works, I'm wondering if there isn't another already-established "c++ way" of doing this.
虽然这种方法完全有效,但我想知道是否没有另一种已经建立的“c++ 方式”来做到这一点。
Thanks for the help! Dan
谢谢您的帮助!担
回答by Matthieu M.
You should try not to use new, to begin with, as using it brings the trouble of memory management.
你应该尽量不要使用new,首先,因为使用它会带来内存管理的麻烦。
For your example, just do the following:
对于您的示例,只需执行以下操作:
int main(int, char*[])
{
SomeObject myObject;
// two phases
ParamClass foo(...);
myObject.myMethod(foo);
// one phase
myObject.myMethod(ParamClass(...));
return 0;
}
I recommend the first method (in two times) because there are subtle gotchas with the second.
我推荐第一种方法(两次),因为第二种方法有一些微妙的问题。
EDIT: comments are not really appropriate to describe the gotchas I was referring to.
编辑:评论并不适合描述我所指的问题。
As @Fred Nurkcited, the standard says a few things about the lifetime of temporaries:
正如所@Fred Nurk引用的,该标准说明了有关临时文件生命周期的一些内容:
[class.temporary]
[类.临时]
(3) Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.
(5) The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference [note: except in a number of cases...]
(5) [such as...] A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
(3) 临时对象被销毁作为评估(词汇上)包含它们创建点的完整表达式(1.9)的最后一步。即使该评估以抛出异常结束,也是如此。销毁临时对象的值计算和副作用仅与完整表达式相关,与任何特定子表达式无关。
(5) 引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在 [注意:除了在许多情况下...]
(5) [例如...] 函数调用中引用参数的临时绑定 (5.2.2) 一直存在,直到包含调用的完整表达式完成。
This can lead to two subtle bugs, that most compilers do not catch:
这会导致两个微妙的错误,大多数编译器都没有发现:
Type const& bound_bug()
{
Type const& t = Type(); // binds Type() to t, lifetime extended to that of t
return t;
} // t is destroyed, we've returned a reference to an object that does not exist
Type const& forwarder(Type const& t) { return t; }
void full_expression_bug()
{
T const& screwed = forwarder(T()); // T() lifetime ends with `;`
screwed.method(); // we are using a reference to ????
}
Argyrios patched up Clang at my request so that it detects the first case (and a few more actually that I had not initially thought of). However the second can be very difficult to evaluate if the implementation of forwarderis not inline.
Argyrios 应我的要求修补了 Clang,以便它检测到第一种情况(实际上还有一些我最初没有想到的情况)。但是,如果 的实现forwarder不是内联的,则第二个可能非常难以评估。
回答by Raedwald
Try:
myObject.myMethod(ParamClass(...));in C++, unlike Java, you do not always need to say newto create a new object.
尝试:
myObject.myMethod(ParamClass(...));在 C++ 中,与 Java 不同,您不必总是说new要创建一个新对象。
回答by Mark Ransom
The established way of doing it is with an automatic local variable:
已建立的方法是使用自动局部变量:
ParamClass myParam;
myOjbect.myMethod(myParam);
By using newin the way you did, you're generating a memory leak. Nothing will dispose of that object once the function returns - C++ does not have garbage collection as some other languages do.
通过以new您所做的方式使用,您会产生内存泄漏。一旦函数返回,就不会处理该对象 - C++ 不像其他一些语言那样具有垃圾收集功能。
回答by Frederik Slijkerman
You need to be aware of the lifetime of the object. If you pass *new ParamClassto a function, you're giving ownership of the new object to the function. If the function does not destroy it (and it should never do that given a reference), you'll get a memory leak.
您需要了解对象的生命周期。如果传递*new ParamClass给函数,则将新对象的所有权授予该函数。如果该函数没有销毁它(并且在给定引用的情况下它永远不应该这样做),则会出现内存泄漏。
Instead, you should do something like this:
相反,您应该执行以下操作:
ParamClass myParamClass(...);
myObject.myMethod(myParamClass);
回答by Armen Tsirunyan
When you write
当你写
myObject.myMethod(*new ParamClass(...));
you lose the pointer to the new'd object. That is, this will work, but you won't be able to later deletethe object. So you can do this:
你失去了指向新对象的指针。也就是说,这将起作用,但您将无法稍后处理delete该对象。所以你可以这样做:
ParamClass pc(...);
myObject.myMethod(pc);
or, easier
或者,更容易
myObject.myMethod(ParamClass(...));
or, if dynamic allocation is necessary for some inexplicable reason
或者,如果出于某种莫名其妙的原因需要动态分配
ParamClass* pPc = new ParamClass(...);
myObject.myMethod(*pPc);
...
delete pPc;
or, use smart pointers to avoid manual deletion. Something like:
或者,使用智能指针来避免手动删除。就像是:
boost::scoped_ptr<ParamClass> spPc(new ParamClass(...));
myObject.myMethod(*pPc);
Hope this helps
希望这可以帮助
回答by Infintyyy
Just note that there is big difference between assigning the value of an object (I mean the object of the user defined class) previously created to new object in java and c++ , and it is about :
请注意,将先前创建的对象(我的意思是用户定义类的对象)的值分配给 java 和 c++ 中的新对象之间存在很大差异,它是关于:
1- in C++: object new =(object) older [ create a copy of the object older to newer and when you modify newer ,the older will notchange !]
1- 在 C++ 中:object new =(object) old [创建一个从旧到新的对象的副本,当你修改新的时,旧的不会改变!]
2- in java: object new =(object) older [create a reference to the older object and when you modify the newer , the older also willchange (very very important)]
2-在java中:object new =(object) old [创建对旧对象的引用,当你修改新对象时,旧对象也会改变(非常非常重要)]
conclusion :
结论 :
in java : "object new =(object) older" is the same as "object &new =(object) older" in c++.
在 Java 中:“object new =(object) old”与 C++ 中的“object &new =(object) old”相同。

