[英]Are const class members useful when the assignment operator is overloaded?
我有一個類,其成員不會被類的方法更改,所以我將其標記為const
。 我的問題是我使用默認賦值運算符就像復制構造函數一樣,以避免多個聲明。 但在這種情況下,賦值運算符不會自動生成,因此我得到一些編譯器錯誤: 'operator =' function is unavailable
。 這似乎沒有真正的生活場景,其中可以實際使用const類成員(例如,你在STL代碼中看到過任何const成員嗎?)。
有沒有辦法解決這個問題,除了刪除const
?
編輯 :一些代碼
class A
{
public :
const int size;
A(const char* str) : size(strlen(str)) {}
A() : size(0) {}
};
A create(const char* param)
{
return A(param);
}
void myMethod()
{
A a;
a = create("abcdef");
// do something
a = create("xyz");
// do something
}
以下是導致此問題的誤解:
[..]這個方法沒有改變
該成員變量是由類,賦值運算符的方法改變。 包括由編譯器合成的一個。 如果將成員變量標記為const
,則表示此變量將(不應該!)在對象的生命周期內更改其值。 很明顯,為對象分配新值違反了此聲明。 因此,如果您確實不希望成員更改,請不要將其設為const
。
const
成員在許多情況下是理想的。 當然,有一個明顯的情況是值不應該或不能改變,但它也是優化和並發的一個重要限制 - 不是每個類型都需要或應該有賦值運算符。
如果成員需要賦值行為,那么變量不能是const
。
當值/成員不能突變或通過進行突變this
,它更清晰,以提供(在更復雜的情況,甚至是亞型>組合物)為變量的成員單獨的接口:
class t_text {
public:
// ...
public:
void setString(const std::string& p);
private:
const t_text_attributes d_attributes;
std::string d_string;
};
因此,我的建議是隱藏賦值運算符,並使“可變塊”或成員可設置為清晰:
text.setString("TEXT"); // << Good: What you read is what happens.
text = otherText; // << Bad: Surprise - attributes don't actually change!
你不能擁有const
成員和支持賦值,至少不能賦予預期的語義。 從邏輯上講, const
是一個成員永遠不會改變的承諾,並且(隱含地,在大多數人的頭腦中)賦予所有數據成員將采用右手成員的價值的承諾(這通常意味着改變)。 這兩個承諾之間存在着非常明確的沖突。
當然,很多類型不應該支持任務開始; 對於不支持賦值的類型,聲明數據成員const
沒有問題。 但總的來說,我發現const
在這里const
用處; const
是合同的一部分,數據成員通常不是該類外部合同的一部分。 (但很大程度上取決於 - 如果數據成員是公共的或受保護的,那么它是不可變的這一事實可能是外部合同的一部分。當然,在語言結構中表達內部類不變量也沒有錯。)
是的,您可以覆蓋賦值運算符。
因為您使用的是默認值,編譯器也會嘗試復制const
成員。 這是非法的,因為它是const
。
class A
{
private:
const int a;
public :
A() : a(0) {}
A& operator = (const A& other) {return *this;}
};
int main()
{
A a;
A b;
a = b; //this is legal if operator = is declared
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.