2014-09-01 79 views
5

以下代碼給出了一個編譯錯誤在(至少使用當MS VS 2008)線 「E = F」 主():錯誤C2582: '運算符=' 的功能是在 'B' 不可用

錯誤C2582: '運算符=' 功能是

class A { 
public: 
    A() { } 
    static const double x; 
}; 
const double A::x = 0.0; 

class B { 
public: 
    B() : x(0.0) { } 
    const double x; 
}; 

int main(int argc, char *argv[]) 
{ 
    A c,d; 
    B e,f; 

    c = d; 
    e = f; 

    return 0; 
} 

默認賦值運算符應爲兩個類,A和B可以產生 'B' 不可用!?

in 12.8.10:「如果類定義沒有明確聲明 複製賦值運算符,則會隱式聲明一個運算符。」

回答

14

隱式生成的運算符將遞歸地分配每個非靜態成員。但是,xconst,因此無法分配給它。這可以防止生成隱式運算符(具體而言,它會導致它被定義爲已刪除)。

這被指定在C++ 11 12.8/23:

類X A拖欠複製/移動賦值運算符被定義爲已刪除如果X具有:

  • ...
  • const的非類類型(或其陣列)的非靜態數據成員,或者
  • ...

(雖然我剛剛注意到你的編譯器早於C++ 11;規則是相似的,但是用不同的語言規定,在老方言中沒有「刪除」功能的概念)。

如果您想爲其成員(或基類)無法重新分配的類的賦值運算符,則必須自己定義它。

class A中,常量成員是靜態成員,因此不構成對象的一部分。因此,它不會阻止將(空)對象分配給。

2

A類和B類之間的明顯區別是const成員x是靜態與非靜態。 對const變量的賦值在任何情況下都是不可能的。

編譯器顯然會嘗試爲類B生成默認的賦值運算符方法,並默默決定不生成一個,因爲成員x不允許賦值。

我花了相當長的時間來找出這個......

順便說一句:如果你省略B類x的初始化,編譯器足夠聰明,找出這個錯誤。

+4

是的,你回答了你自己的問題。如果你接受你的答案,你會得到一個徽章(但沒有代表)。 – CashCow 2014-09-01 13:24:57

4

'x'const double const限定型的,默認的賦值運算符將是毫無意義的,是含蓄刪除這裏