如何 return 引用在方法内创建的对象

How to return references to object created inside a method

我正在推理 return 对在方法内创建的对象的引用的最佳方法,如以下情况:

class A{
public:
    A(){}
    ~A(){}
};

class Foo{
public:
    Foo(){}
    ~Foo(){}
    A& create(int random_arg){
         // create object A and return its reference
    }
};

void other_method(){
     Foo f;
     A a = f.create();
     // do stuff with a
{

我考虑了三种可能的解决方案:

  1. 创建原始指针和 return 引用,但这很糟糕,因为不能保证对象将被正确删除:

    A& create(int random_arg){
         A* a = new A();
         return *a;
    }
    
  2. 按值创建 shared_ptr 和 return shared_ptr。这样 shared_ptr 将负责对象删除:

    shared_ptr<A> create(int random_arg){
         boost::shared_ptr<A> a_ptr(new A());
         return a_ptr;
    }
    
  3. 创建一个 shared_ptr 和 return 一个引用:

    A& create(int random_arg){
         boost::shared_ptr<A> a_ptr(new A());
         return *a_ptr;
    }
    

第二个方案好像用的最多,但是这样我就得在应用中铺shared_ptr而且我更希望有参考,或者更好的const参考。

您认为处理这种情况的最佳方法是什么?还有其他我没有考虑过的可能性吗?

不要这样做。您很可能有一个 悬空引用 .

只是 return A 的实例值。

编译器很可能会删除隐含的对象副本。但是您可以保证不会通过为A.

编写移动构造函数来创建对象副本。

之所以 return 将指针或引用指向局部变量是一个坏主意,是因为它们通常在堆栈上,这意味着当堆栈再次到达该深度时,数据将被覆盖和损坏.

新手经常犯这样的错误,因为它经常碰巧是靠运气而让我放心的,即当你在调用任何其他函数破坏堆栈帧之前直接使用 returned 指针时上一个的。

按值返回可能适用于许多情况,编译器可以自由优化return。但即使没有优化,它也可能不是什么大问题,例如在 Qt 中,所有容器和许多其他 类 都隐式共享资源,因此 return 复制并不会真正复制所有数据,只是对象的 shell,通常是指向实际数据的单个指针。 C++ 中也有移动语义,这在这方面有点相似 - 它将责任从本地转移到 returned 对象而不进行深层复制。

有两种主要情况下 return 不需要按值。

  • 如果涉及不可避免的重物复制
  • 如果它是一个带有 "identity" 的对象——它们的复制构造函数和赋值运算符被禁用,所以它们不能真正被 return 按值编辑

在这些情况下,您只需动态分配对象并 return 指向它的指针。无论您是手动管理它还是更喜欢使用智能指针 - 这取决于您的需要。

完成 Bathsheba 的回答:

只有一种情况下您可能想要执行类似的操作,即如果您要将实例返回给单例。在这种情况下,这样的实例将是一个静态对象:

A& getTheOnlyInstanceOfA()
{
   static A onlyInstOfA;
   return onlyInstOfA; 
}