返回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!
相關文章
相關標籤/搜索