返回C ++引用变量的作法是邪恶的吗?

我以为这有点主观; 我不肯定这个意见是否会一致(我已经看过不少代码片断,其中返回了引用)。 安全

根据对这个问题的评论我刚刚问过,关于初始化引用 ,返回引用多是邪恶的,由于,[据我所知]它更容易错过删除它,这可能致使内存泄漏。 app

这让我很担忧,由于我跟随了一些例子(除非我想象事情)而且在至关多的地方作过这样的事情......我误解了吗? 这是邪恶的吗? 若是是这样,那有多邪恶? 函数

我以为由于个人指针和引用混合在一块儿,再加上我是C ++的新手,以及对何时使用的彻底混淆,个人应用程序必须是内存泄漏地狱...... spa

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


#1楼

关于可怕的代码: code

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

确实,返回后内存指针丢失了。 可是若是你像这样使用shared_ptr: 对象

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

返回后内存不会丢失,并在分配后释放。 生命周期


#2楼

返回引用一般在C ++中用于大型Object的运算符重载,由于返回值须要复制操做。(在perator重载中,咱们一般不使用指针做为返回值) 内存

可是返回引用可能会致使内存分配问题。 由于对结果的引用将做为对返回值的引用传递出函数,因此返回值不能是自动变量。 element

若是你想使用返回引用,你可使用静态对象的缓冲区。 例如

const max_tmp=5; 
Obj& get_tmp()
{
 static int buf=0;
 static Obj Buf[max_tmp];
  if(buf==max_tmp) buf=0;
  return Buf[buf++];
}
Obj& operator+(const Obj& o1, const Obj& o1)
{
 Obj& res=get_tmp();
 // +operation
  return res;
 }

经过这种方式,您能够安全地使用返回参考。

可是你老是可使用指针而不是引用来返回functiong中的值。


#3楼

我认为使用引用做为函数的返回值比使用指针做为函数的返回值要简单得多。 其次,使用返回值所引用的静态变量老是安全的。


#4楼

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

在函数中分配对象并将其做为引用或指针返回(然而指针更安全)是很差的主意,由于在函数块的末尾释放了内存。


#5楼

我发现答案不尽如人意,因此我会加两分钱。

咱们来分析下列状况:

错误的使用

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

这在实现Singleton模式时也很常见

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!
相关文章
相关标签/搜索