考慮這個代碼:
#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;
struct BigInteger
{
vector<int> arr;
BigInteger()
{
cout << "default constructor" << endl;
this->arr.push_back(0);
}
BigInteger(initializer_list<int> il)
{
cout << "initializer_list constructor" << endl;
for (const int x : il)
{
arr.push_back(x);
}
}
BigInteger(const BigInteger& obj) //copy constructor
{
cout << "copy constructor" << endl;
this->arr = obj.arr;
}
BigInteger(BigInteger&& obj) //move constructor
{
cout << "move constructor" << endl;
swap(*this, obj);
}
~BigInteger() //destructor
{
cout << "destructor" << endl;
arr.clear(); //probably because of RAII, I guess I don't have to write this
}
BigInteger& operator=(const BigInteger& rhs)
{
cout << "copy assignment" << endl;
BigInteger tmp(rhs);
this->arr = tmp.arr;
return *this;
}
BigInteger& operator=(BigInteger&& rhs) noexcept
{
cout << "move assignment" << endl;
swap(*this, rhs);
return *this;
}
};
int main()
{
BigInteger another = BigInteger({0, 1, 2});
}
所以,我正在創建一個臨時物件BigInteger({0, 1, 2}),然后為我的類實體a(理論上)進行移動分配。所以預期輸出是:
initializer_list 建構式 //創建臨時物件
默認建構式//創建glvalue(非臨時)物件
移動分配
解構式
但輸出是:
initializer_list 建構式
解構式
我什至不明白為什么會這樣。我懷疑這operator=與初始化不同,但我仍然不明白我的物件是如何構造的。
uj5u.com熱心網友回復:
首先,不會呼叫移動賦值運算子,因為您沒有分配任何內容。Type name = ...;是初始化,而不是賦值。
此外,甚至沒有移動構造,因為BigInteger({0, 1, 2})是與初始化物件相同型別的純右值,因此不會實作臨時物件,而是使用純右值的初始化器another直接初始化,就好像您已經寫過一樣BigInteger another = {0, 1, 2};(順便說一句,我建議您撰寫;根本不需要重復該型別)。
我懷疑 operator= 與初始化不同
這是對的。賦值運算子和初始化是兩個獨立的事情。在此示例中您沒有使用賦值運算子。
uj5u.com熱心網友回復:
因此,我正在創建一個臨時物件 BigInteger({0, 1, 2}) 然后為我的類實體 a (理論上)執行移動分配。
似乎您的意思是移動構造而不是移動分配,因為您在談論聲??明。
來自 C 14 標準(12.8 復制和移動類物件)
31 當滿足某些標準時,允許實作省略類物件的復制/移動構造,即使為復制/移動操作選擇的建構式和/或物件的解構式有副作用。在這種情況下,實作將省略的復制/移動操作的源和目標視為參考同一物件的兩種不同方式,并且該物件的銷毀發生在兩個物件本應被洗掉的時間中的較晚時間在沒有優化的情況下銷毀。 122 這種復制/移動操作的省略,稱為復制省略,在以下情況下是允許的(可以合并以消除多個副本):
(31.3) — 當沒有系結到參考的臨時類物件 (12.2) 將被復制/移動到具有相同 cv-unqualified 型別的類物件時,可以通過構造臨時物件來省略復制/移動操作直接進入省略復制/移動的目標
所以在這個宣告中
BigInteger another = BigInteger({0, 1, 2});
通過將臨時物件直接構造到省略的復制/移動的目標中來省略移動操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/356502.html
上一篇:強制物件狀態不變的解決方案
下一篇:訪問類中的屬性
