C++ C++;返回对新对象的引用

C++ C++;返回对新对象的引用,c++,pointers,reference,C++,Pointers,Reference,我知道有类似的问题,但没有一个能给我的问题一个明确的答案 就最佳实践而言,这两个都可以吗?还是应该返回指针? 如果没有,应该如何改变它们以遵循最佳实践 我想从函数返回对新对象的引用。我的执行情况如下: MyClass& doSomething() { return *(new MyClass()); } MyClass a = doSomething(); 这可以吗,因为堆上正在分配一个MyClass的新实例,其中包含new 或者我应该让它保持不变(我真的不确定什么时候该这么做

我知道有类似的问题,但没有一个能给我的问题一个明确的答案

就最佳实践而言,这两个都可以吗?还是应该返回指针? 如果没有,应该如何改变它们以遵循最佳实践

我想从函数返回对新对象的引用。我的执行情况如下:

MyClass& doSomething() {
   return *(new MyClass());
}

MyClass a = doSomething();
这可以吗,因为堆上正在分配一个MyClass的新实例,其中包含new

或者我应该让它保持不变(我真的不确定什么时候该这么做)

如果这两个都是错误的,我应该返回一个指向新对象的指针吗


谢谢。

虽然这并不完全无效,但这不是一个好主意

MyClass& doSomething() {
   return *(new MyClass());
}
返回后,没有人拥有原始指针,因此没有人会
删除它。*因此这是内存泄漏

除非您有相应的
delete
,或者更好的是,有一个智能指针构造函数,否则您几乎不应该编写
new


同时,您的原始代码中的这一行:

MyClass a = doSomething();
…无论如何都要复制该值。假设这不是另一个必须修复的bug,为什么还要麻烦堆分配一个对象并返回一个复制和泄漏的引用呢?只需按值返回对象:

MyClass doSomething() {
   return MyClass();
}
现在您不必担心删除任何内容,因为您从未在堆上创建过任何内容


最佳实践通常可以总结为四个字母RAII:资源获取是初始化。(必然的结果是,这种破坏就是释放。)如果你有一些不可能或昂贵的东西,可以通过值来传递,那么就通过值来传递一些句柄。例如:

unique_ptr<MyClass> doSomething() {
    return unique_ptr<MyClass>(new myClass());
}

unique_ptr<MyClass> a = doSomething();
unique_ptr doSomething(){
返回unique_ptr(new myClass());
}
唯一的_ptr a=剂量测量();
现在它只是一个被复制的指针。对象本身在
doSomething
内部创建,并在
a
超出范围时删除(或者,如果将其传递给另一个变量,则在该变量超出范围时删除,等等)

另一方面,如果
MyClass
只是一些易于复制的值**,那么只需复制它即可


*删除它并非不可能;您可以始终使用指向引用的指针,然后
删除该引用。你不太可能这样做,而且看起来很尴尬。如果要传递指针,请传递指针。如果不想传递指针,请将所有权封装在类中,并按值传递该类


**我所说的“易于复制”是指安全地复制它们是很容易的,而且你实际上是这样做的。例如,一个原始指针或一个文件句柄只有几个字节,默认的复制构造函数会很乐意为您复制它们……但是,您最终会得到对同一堆对象或文件的多个引用,并且不可能跟踪谁负责删除或关闭它。

无需常量,第一个选项很好。此外,如果需要,还可以返回指针。由您决定。但是调用方未分配引用。它是在调用过程中实例化的。因此,我认为如果不使用new,那么它将超出范围,因为它将位于堆栈上而不是堆上。@BrianCain他绝对需要
new
,否则一旦
doSomething()
完成,对象就会被破坏。@SergeSeredenko,对不起,后者是否假定没有RVO?还是我错过了什么。。。(我经常这样做,如果是的话,我会很惊讶)。@WhozCraig:无论是否使用RVO,编译器都无法优化新创建的指针,因为您明确要求它。如果您通过值而不是引用返回,那么RVO可以优化出一个副本,整个过程基本上是免费的?谢谢你的内存泄漏信息,我觉得有些奇怪,但我不太明白是什么。基本上我创建的是一种工厂方法。那么,返回一个指针应该可以吗?我是说你的最后一个关于后续句子的片段,但我现在看到它是关于OP的代码,而不是一个毯子,反正这会复制,所以就这样做吧。我同意,无论是RVO还是move施工,按价值计算都是实现这一目标的根本途径。我甚至没有注意到他在
a
decl+初始化器上泄漏内存。回答得好,顺便说一句+1@SergeSeredenko当前位置我意识到在原始版本中有点难以理解。最近一次编辑后是否足够清晰?谢谢
unique_ptr<MyClass> doSomething() {
    return unique_ptr<MyClass>(new myClass());
}

unique_ptr<MyClass> a = doSomething();