簡體   English   中英

C ++返回局部變量的const引用

[英]c++ returning const reference of local variable

即使函數返回的值是該函數的局部變量,是否也可以返回const引用? 我知道函數返回后,本地方法不再有效-但是如果函數內聯並且返回的值僅在調用者作用域內使用,該怎么辦? 那么該函數的本地變量應該包含在調用者堆棧框架中,對嗎?

不要指望它。 即使這適用於1個編譯器,也不是標准支持的行為,並且很可能會破壞其他行為。

不,那不行。 局部變量在堆棧上聲明,並且堆棧在方法調用之間不斷變化。 同樣,超出范圍的對象也將被銷毀。 始終返回局部變量的副本。

考慮以下代碼:

#include <iostream>
using namespace std;

class MyClass
{
public:
  MyClass() { cout << "ctor" << endl; }
  ~MyClass() { cout << "dtor" << endl; }
  MyClass(const MyClass& r) { cout << "copy" << endl; }
};

const MyClass& Test()
{
  MyClass m;
  return m;
}

int main()
{
  cout << "before Test" << endl;
  MyClass m = Test();
  cout << "after Test" << endl;
}

這將打印出:

before Test
ctor
dtor
copy
after Test
dtor

您要復制的對象已調用其析構函數,並且可能處於無效狀態。

inline 不是保證-這是一個建議 即使使用技巧強制內聯,也永遠無法確定結果,特別是如果您希望保持可移植性。

因此, 請不要這樣做。

這樣做會引起未定義的行為。

  • 無法強迫編譯器內聯函數。 inline只是一個建議__forceinline也是如此
  • 即使您可以保證函數將內聯,有關變量的析構函數仍將執行,從而為死對象提供引用。
  • 而最大的一環-C ++的堆棧概念是通過作用域而不是功能來界定的。

#include <iostream>
int main()
{
  {
    int a = 5;
    std::cout << std::hex << "0x" << &a << std::endl;
  }
  {
    int b = 10;
    std::cout << std::hex << "0x" << &b << std::endl;
  }
}

我的編譯器將“ a”和“ b”放在不同的內存地址。 除了我打開優化功能時。 您可能會決定,重新使用對象先前占用的內存是一種優化。

您要在這里解決一個特別的問題嗎? 如果您擔心的話,還有其他方法可以減少創建的臨時對象的數量。

正如其他人指出的那樣,這很危險。 如果您的編譯器支持NRVO(命名返回值優化),並且您的函數使用並返回您希望通過ref以相當簡單的方式返回的局部變量,則這也是不必要的。

NRVO允許編譯器在某些條件下避免復制構造-這通常是避免按值返回對象的主要原因。 VC ++ 8支持此功能(在以前的版本中為增量),並且在經常使用的代碼中使性能差異相當大。

當被叫方超出范圍時,該值超出范圍。 所以不,它消失了。

但是,如果您想要一個相當丑陋的解決方案(並且發出紅旗警告您您的設計可能需要重構),則可以執行以下操作:

const MyObj& GetObj()
{
  static const MyObj obj_;
  return obj_;
}

...但是如果遇到危險,尤其是如果對象是可修改的,或者在多線程環境中執行不重要的操作時,此解決方案就會充滿危險。

inline關鍵字不能保證函數真正內聯。 不要這樣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM