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

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

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

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

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


当前回答

我发现这些答案不令人满意,所以我要发表我的意见。

让我们来分析以下案例:

错误的用法

int& getInt()
{
    int x = 4;
    return x;
}

这显然是错误的

int& x = getInt(); // will refer to garbage

静态变量的使用

int& getInt()
{
   static int x = 4;
   return x;
}

这是正确的,因为静态变量在程序的整个生命周期中都存在。

int& x = getInt(); // valid reference, x = 4

这在实现单例模式时也很常见

class Singleton
{
    public:
        static Singleton& instance()
        {
            static Singleton instance;
            return instance;
        };

        void printHello()
        {
             printf("Hello");
        };

};

用法:

 Singleton& my_sing = Singleton::instance(); // Valid Singleton instance
 my_sing.printHello();  // "Hello"
    

运营商

标准库容器在很大程度上依赖于返回引用的操作符的使用

T & operator*();

可用于以下

std::vector<int> x = {1, 2, 3}; // create vector with 3 elements
std::vector<int>::iterator iter = x.begin(); // iterator points to first element (1)
*iter = 2; // modify first element, x = {2, 2, 3} now

快速访问内部数据

有时&可以用于快速访问内部数据

Class Container
{
    private:
        std::vector<int> m_data;

    public:
        std::vector<int>& data()
        {
             return m_data;
        }
}

的用法:

Container cont;
cont.data().push_back(1); // appends element to std::vector<int>
cont.data()[0] // 1

然而,这可能会导致如下陷阱:

Container* cont = new Container;
std::vector<int>& cont_data = cont->data();
cont_data.push_back(1);
delete cont; // This is bad, because we still have a dangling reference to its internal data!
cont_data[0]; // dangling reference!

其他回答

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

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

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

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

函数作为左值(也就是返回非const引用)应该从c++中删除。这太不直观了。Scott Meyers想要一个min()的行为。

min(a,b) = 0;  // What???

这并不是真正的进步

setmin (a, b, 0);

后者甚至更有意义。

我意识到函数作为左值对于c++风格的流很重要,但值得指出的是,c++风格的流很糟糕。我不是唯一一个这样认为的人……我记得Alexandrescu有一篇关于如何做得更好的文章,我相信boost也试图创建一个更好的类型安全的I/O方法。

这并不邪恶。像c++中的许多东西一样,如果使用正确,它是好的,但在使用它时应该注意许多陷阱(比如返回对局部变量的引用)。

有一些好的东西可以用它来实现(比如map[name] = "hello world")

最好的方法是创建对象并将其作为引用/指针形参传递给分配该变量的函数。

在函数中分配对象并将其作为引用或指针返回(但指针更安全)是一个坏主意,因为会在函数块的末尾释放内存。

我发现这些答案不令人满意,所以我要发表我的意见。

让我们来分析以下案例:

错误的用法

int& getInt()
{
    int x = 4;
    return x;
}

这显然是错误的

int& x = getInt(); // will refer to garbage

静态变量的使用

int& getInt()
{
   static int x = 4;
   return x;
}

这是正确的,因为静态变量在程序的整个生命周期中都存在。

int& x = getInt(); // valid reference, x = 4

这在实现单例模式时也很常见

class Singleton
{
    public:
        static Singleton& instance()
        {
            static Singleton instance;
            return instance;
        };

        void printHello()
        {
             printf("Hello");
        };

};

用法:

 Singleton& my_sing = Singleton::instance(); // Valid Singleton instance
 my_sing.printHello();  // "Hello"
    

运营商

标准库容器在很大程度上依赖于返回引用的操作符的使用

T & operator*();

可用于以下

std::vector<int> x = {1, 2, 3}; // create vector with 3 elements
std::vector<int>::iterator iter = x.begin(); // iterator points to first element (1)
*iter = 2; // modify first element, x = {2, 2, 3} now

快速访问内部数据

有时&可以用于快速访问内部数据

Class Container
{
    private:
        std::vector<int> m_data;

    public:
        std::vector<int>& data()
        {
             return m_data;
        }
}

的用法:

Container cont;
cont.data().push_back(1); // appends element to std::vector<int>
cont.data()[0] // 1

然而,这可能会导致如下陷阱:

Container* cont = new Container;
std::vector<int>& cont_data = cont->data();
cont_data.push_back(1);
delete cont; // This is bad, because we still have a dangling reference to its internal data!
cont_data[0]; // dangling reference!