[英]I thought array was non copyable
我的印象是陣列是不可復制的(或可分配的)。
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,0};
x = y; // Fails to compile
但是當我在一個類中放入一個數組時,復制構造函數和賦值運算符工作(我會按預期說,但它不是我所期望的)。
#include <iostream>
struct X
{
virtual ~X(){} // Just in case it was something to do with POD
// make sure its not a POD
int x[5];
};
int main()
{
X a;
a.x[0] = 0;
a.x[1] = 1;
a.x[2] = 2;
a.x[3] = 3;
a.x[4] = 4;
// Make a copy of a and test it
X b(a);
std::cout << a.x[0] << " : " << b.x[0] << "\n";
b.x[0] = 10;
b.x[1] = 11;
b.x[2] = 12;
b.x[3] = 13;
b.x[4] = 14;
// Now that we have modified 'b' make sure it is unique.
std::cout << a.x[0] << " : " << b.x[0] << "\n";
// Use assignment and see if it worked.
b = a;
std::cout << a.x[0] << " : " << b.x[0] << "\n";
}
編譯並運行
> g++ t.cpp
> ./a.out
0 : 0
0 : 10
0 : 0
這里發生了什么?
默認的復制構造函數和賦值運算符分別對每個成員使用復制構造和賦值。 當有數組時,在數組的每個元素上使用復制構造或賦值(這是非常明確的)。
這是規則,從第12.8節( [class.copy]
):
非聯合類
X
的隱式定義的復制/移動構造函數執行其基礎和成員的成員復制/移動。 [注意:忽略非靜態數據成員的大括號或大小寫。 另請參見12.6.2中的示例。 - 結束注釋]初始化的順序與用戶定義的構造函數中基數和成員的初始化順序相同(見12.6.2)。 設x
是構造函數的參數,或者對於移動構造函數,x
是引用參數的xvalue。 以適合其類型的方式復制/移動每個基本或非靜態數據成員:
- 如果成員是一個數組,則使用
x
的相應子對象直接初始化每個元素 ;- 如果成員m具有右值引用類型
T&&
,則使用static_cast<T&&>(xm)
直接初始化;- 否則,用
x
的相應基數或成員直接初始化基數或成員。
和
非聯合類
X
的隱式定義的復制/移動賦值運算符執行其子對象的成員復制/移動分配。 首先按照它們在base-specifier-list中的聲明順序分配X
的直接基類,然后按照它們在類定義中聲明的順序分配X
的直接非靜態數據成員。 。 設x
是函數的參數,或者對於move運算符,是指參數的xvalue。 每個子對象都以適合其類型的方式分配:
- 如果子對象是類類型,就好像通過調用operator =將子對象作為對象表達式而x的對應子對象作為單個函數參數(就像通過顯式限定;即忽略任何可能的虛擬覆蓋函數在更多派生類中);
- 如果子對象是一個數組,則以適合於元素類型的方式分配每個元素 ;
- 如果子對象是標量類型,則使用內置賦值運算符。
C::C(const C&)
與C::C(C&)
等之間的簽名選擇規則還包括引用數組元素類型的語言。
數組既不可復制也不可賦值。 但是,具有數組成員的結構已生成復制構造和復制分配。 這是一項特殊規則:即它們本身不需要是可復制的或可分配的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.