簡體   English   中英

如果類具有引用數據成員,為什么默認賦值運算符不由編譯器合成

[英]Why a default assignment operator not synthesis by compiler if a class has a reference data member

在C ++中,如果類具有引用數據成員,則默認賦值運算符不由編譯器合成。 為什么?

在C ++中,如果類具有引用數據成員,則默認賦值運算符不由編譯器合成。 為什么?

副本分配應該做什么定義如下:

C ++ 03標准12.8 / 13:

每個子對象都以適合其類型的方式分配:

  • 如果子對象是類類型,則使用該類的復制賦值運算符(就好像通過顯式限定;即忽略更多派生類中的任何可能的虛擬覆蓋函數);

  • 如果子對象是一個數組,則以適合於元素類型的方式分配每個元素;

  • 如果子對象是標量類型,則使用內置賦值運算符。

簡而言之,它意味着每個成員都應以適當的方式分配
提出了這個問題,
在課堂上分配參考成員的行為應該是什么?
請考慮以下有關參考:

  1. 引用本質上是不可轉讓的,它們一直引用與它們被初始化的相同的引用[參考文獻1]
  2. 由於#1分配給引用不會重新分配引用,它會更改引用的值,這是非直觀的行為。

這里沒有要執行的默認正確行為,而是一個相當情境化的行為。所以C ++標准要求類的設計者最有能力確定這種行為,因此決定默認賦值運算符不應由編譯器合成。 class有一個引用數據成員。

該決定在以下內容中規定:
C ++ 03標准12.8 / 12:

當為其類類型的對象分配其類類型的值或從其類類型派生的類類型的值時,將隱式定義隱式聲明的復制賦值運算符。 如果隱式定義了復制賦值運算符的類具有以下內容,則程序生成錯誤:
.......
- 引用類型的非靜態數據成員,或
.......


[參考1]
C ++ 03標准8.5.3 / 2:

初始化后,無法更改引用以引用另一個對象 請注意,引用的初始化與賦值的處理方式非常不同。 參數傳遞(5.2.2)和函數值返回(6.6.3)是初始化。

在僅限會員的論壇上看到了討論。 由於答案並不為大多數程序員所熟知,因此想發布答案並在此處分享。

從C ++標准草案N3337§12.8.23:

如果X具有以下內容,則將類X的默認復制/移動賦值運算符定義為已刪除:

  • 具有非平凡對應賦值運算符的變體成員,X是類似聯合的類,或
  • const非類型(或其數組)的非靜態數據成員,或
  • 引用類型的非靜態數據成員,或
  • 類型M(或其數組)的非靜態數據成員,由於應用於M的相應賦值運算符的重載決策(13.3),無法復制/移動,導致模糊或被刪除或無法訪問的函數默認的賦值運算符,或
  • 由於應用於B的相應賦值運算符的重載決策(13.3),無法復制/移動的直接或虛擬基類B導致模糊或從默認賦值運算符中刪除或無法訪問的函數,或者
  • 對於移動賦值運算符,非靜態數據成員或直接基類,其類型不具有移動賦值運算符,並且不是簡單可復制的,或任何直接或間接虛擬基類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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