[英]const reference to temporary and copying - C++
請考慮以下代碼,
struct foo
{
foo()
{
std::cout << "Constructing!" << std::endl;
}
foo(const foo& f)
{
std::cout << "Copy constructing!" << std::endl;
}
~foo()
{
std::cout << "Destructing.." << std::endl;
}
};
foo get()
{
foo f;
return f;
}
int main()
{
const foo& f = get();
std::cout << "before return" << std::endl;
return 0;
}
MSVC上的輸出
Constructing!
Copy constructing!
Destructing..
before return
Destructing..
GCC的產出
Constructing!
before return
Destructing..
MSVC上的結果看起來不正確。
問題
const foo& f = get()
和const foo f = get()
產生相同的輸出。 在這種情況下,應該首選哪種寫作方式? 有什么想法嗎..
您的MSVC構建沒有優化。 打開它們,你會得到相同的輸出。
默認情況下,GCC僅對您的臨時執行RVO。 它基本上是這樣做的:
const foo& f = foo();
MSVC不是。 它在函數中創建foo
,將其復制到函數外部(復制構造函數調用),破壞內部foo
,然后綁定引用。
兩個輸出都是正確的。 RVO是標准明確允許程序的可觀察行為發生變化的一個實例。
get()函數是構造本地(print Constructing!),並按值返回Foo對象。 必須創建返回的Foo對象,並通過復制構造(print copy construct!)完成。 請注意,這是在main中分配給const foo&f的對象值。
在進行該賦值之前,函數必須從get()返回,並且必須銷毀局部變量(即foo f;在get()中)。 (print 1st Destructing ..)從那里程序終止(即從main返回)然后get()返回並分配給“f”的對象被銷毀。 (打印第二次破壞...)
您看到兩個編譯器的輸出不同的原因是GCC正在優化get()的返回值,並且只是將const foo &f = get()
替換為const foo &f = foo
;
1)這是因為不同的優化策略。 因為你沒有operator =,所以MSVC可以將代碼重構為const foo&f(get()),從而執行copy onstructor。 2)取決於你想要實現的目標:
const foo& f = get();
f = get(); // Incorrect, const references cannot be reassigned.
const foo g = get();
g = get(); // Correct.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.