簡體   English   中英

當賦值運算符重載時,const類成員是否有用?

[英]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.

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