[英]c++ operator += overloading return reference to
有人可以解釋一下這個算符重載示例Average& operator+=(int num)
的區別是什么,在該示例中,您返回對Average
的引用而不是不返回對Average
的引用,即Average operator+=(int num)
。
返回引用是否意味着返回對分配給*this
的對象的引用(不是副本)。 因此,在這種情況下,返回對對象avg
的引用。
非參考版本如何/為什么起作用? 結果在哪里復制?
#include <iostream>
#include <cstdint> // for fixed width integers
class Average
{
private:
int32_t m_total = 0; // the sum of all numbers we've seen so far
int8_t m_numbers = 0; // the count of numbers we've seen so far
public:
Average()
{
}
friend std::ostream& operator<<(std::ostream &out, const Average &average)
{
// Our average is the sum of the numbers we've seen divided by the count of the numbers we've seen
// We need to remember to do a floating point division here, not an integer division
out << static_cast<double>(average.m_total) / average.m_numbers;
return out;
}
// Because operator+= modifies its left operand, we'll write it as a member
Average& operator+=(int num)
{
// Increment our total by the new number
m_total += num;
// And increase the count by 1
++m_numbers;
// return *this in case someone wants to chain +='s together
return *this;
}
};
int main()
{
Average avg;
avg += 4;
std::cout << avg << '\n';
return 0;
}
在C ++中重寫運算符時,可以以多種形式提供它們。 您可以定義賦值運算符,這些賦值運算符不返回對已修改對象的引用,它們將按預期工作。 但是,對於每個運算符,我們都有所謂的規范實現 :
除了上述限制之外,該語言對重載運算符的操作或返回類型(返回類型(不參與重載解析))沒有任何其他限制,但是通常,重載運算符的行為應盡可能與重載運算符相似。內置運算符:
operator+
應該加而不是乘以其參數,operator=
應該賦值,等等。相關運算符的行為類似(operator+
和operator+=
進行相同的加法運算)。 返回類型受到期望使用該運算符的表達式的限制:例如,賦值運算符通過引用返回,從而可以編寫a = b = c = d
,因為內置運算符允許這樣做。通常,重載運算符具有以下典型的規范形式。
關於這些規范形式有很多文章要閱讀,但是我建議從關於操作符重載的基本規則和慣用法是什么的這個非常好的SO答案開始。
非參考版本如何/為什么起作用?
因為即使C ++標准鼓勵您使用規范形式,也不會禁止您不使用規范形式。
結果在哪里復制?
該值無處被丟棄。 實施可能會優化它們。
返回引用是否意味着返回對分配給該對象的引用(不是副本),即* this。 因此,在這種情況下,返回對對象avg的引用。
是。
非參考版本如何/為什么起作用? 結果在哪里復制?
返回的值是一個臨時對象,該對象傳遞給std::cout <<
。
它類似於使用:
int foo()
{
return 10;
}
std::cout << foo() << std::endl;
foo
的返回值是一個臨時對象,傳遞給std::cout <<
。
您應該返回一個引用,因為多數民眾贊成在標准庫中使用的是多數民眾贊成的慣例。 大多數程序員會期望以下代碼:
std::string s;
(s += "a") = "b";
std::cout << s << std::endl;
打印b
,或在此示例中:
int n = 10;
(n += 20) = 100;
std::cout << n << std::endl;
預計將打印100
張。
這就是為什么您應該返回引用以遵守約定的原因,該約定允許修改位於分配左側的對象。
否則,如果您按上述示例中的值(副本)返回,則將分配給一個臨時對象。
嘗試檢查這個類似的問題 。
返回引用時,實際上是在傳遞實際對象。 當您按值返回時,將創建臨時對象,然后將其傳遞給調用方。
因此,如果您返回但沒有參考,則該分配可能按照上面的代碼段工作。
Average aa = avg += 4;
但是如果嘗試,它將無法編譯。
Average *ptr = &(avg += 4);
如果您返回引用,上述代碼將起作用,因為我們正在傳遞對象的有效范圍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.