我认为这有点主观;我不确定意见是否一致(我见过许多返回引用的代码片段)。

根据对我刚才问的这个问题的评论,关于初始化引用,返回一个引用可能是邪恶的,因为(据我所知)它更容易错过删除它,这可能导致内存泄漏。

这让我很担心,因为我已经遵循了一些例子(除非是我想象的事情),并且在相当多的地方这样做了……我误解了吗?它邪恶吗?如果是的话,到底有多邪恶?

我觉得因为我的指针和引用的混合包,加上我是c++的新手,以及完全不知道什么时候用什么,我的应用程序一定是内存泄漏的地狱…

另外,我知道使用智能/共享指针被普遍认为是避免内存泄漏的最佳方法。


当前回答

您应该返回一个对现有对象的引用,该对象不会立即消失,并且您不打算对其进行任何所有权转移。

永远不要返回对局部变量之类的引用,因为它不会在那里被引用。

你可以返回一个独立于函数的引用,你不希望调用函数负责删除它。典型的运算符[]函数就是这种情况。

如果你正在创建一些东西,你应该返回一个值或一个指针(常规或智能)。您可以自由地返回一个值,因为它将进入调用函数中的变量或表达式。永远不要返回指向局部变量的指针,因为它会消失。

其他回答

No.

不好的是引用动态分配的对象而丢失了原来的指针。当你新建一个对象时,你承担了保证删除的义务。

但是看一下,例如,操作符<<:必须返回一个引用,或者

cout << "foo" << "bar" << "bletch" << endl ;

不能工作。

一般来说,返回引用是非常正常的,并且经常发生。

如果你的意思是:

int& getInt() {
    int i;
    return i;  // DON'T DO THIS.
}

那是各种各样的邪恶。stack-allocated i会消失,你什么都没有提到。这也是恶的。

int& getInt() {
    int* i = new int;
    return *i;  // DON'T DO THIS.
}

因为现在客户最终要做一些奇怪的事情:

int& myInt = getInt(); // note the &, we cannot lose this reference!
delete &myInt;         // must delete...totally weird and  evil

int oops = getInt(); 
delete &oops; // undefined behavior, we're wrongly deleting a copy, not the original

请注意,右值引用仍然只是引用,所以所有邪恶的应用程序都是一样的。

如果你想要分配一些超出函数范围的东西,使用智能指针(或者一般来说,一个容器):

std::unique_ptr<int> getInt() {
    return std::make_unique<int>(0);
}

现在客户端存储了一个智能指针:

std::unique_ptr<int> x = getInt();

引用也可以用于访问你知道生命期在更高级别上保持打开的东西,例如:

struct immutableint {
    immutableint(int i) : i_(i) {}

    const int& get() const { return i_; }
private:
    int i_;
};

在这里,我们知道返回对i_的引用是可以的,因为不管调用我们的是什么,它都管理着类实例的生命周期,所以i_至少会存在这么长时间。

当然,这并没有什么错:

int getInt() {
   return 0;
}

如果生命期应该留给调用者,而你只是在计算值。

总结:如果对象的生命周期不会在调用后结束,则可以返回引用。

关于糟糕的代码:

int& getTheValue()
{
   return *new int;
}

实际上,内存指针在返回后丢失。但是如果你像这样使用shared_ptr:

int& getTheValue()
{
   std::shared_ptr<int> p(new int);
   return *p->get();
}

内存在返回后不会丢失,并将在分配后释放。

“回复推荐信是邪恶的,因为, 只是(据我所知)它造就了它 更容易忘记删除它”

不正确的。返回引用并不意味着所有权语义。也就是说,只是因为你这样做:

Value& v = thing->getTheValue();

...并不意味着你现在拥有由v引用的内存;

然而,这是可怕的代码:

int& getTheValue()
{
   return *new int;
}

如果你这样做是因为“你不需要那个实例上的指针”,那么:1)如果你需要引用,就解除对指针的引用,2)你最终会需要指针,因为你必须用delete匹配new,你需要一个指针来调用delete。

对已接受答案的补充:

Struct immutableint { Immutableint (int i): i_(i) {} Const int& get() Const{返回i_;} 私人: int i_; };

我认为这个例子是不好的,如果可能的话应该避免。为什么?很容易以悬空引用结束。

用一个例子来说明这一点:

struct Foo
{
    Foo(int i = 42) : boo_(i) {}
    immutableint boo()
    {
        return boo_;
    }  
private:
    immutableint boo_;
};

进入危险区域:

Foo foo;
const int& dangling = foo.boo().get(); // dangling reference!