我正在研究自 C 11 以來引入的“移動語意”。我撰寫了一個示例代碼,用于使用普通建構式、復制建構式和移動建構式創建類物件。
/* Useless.cpp */
#include <iostream>
using namespace std;
// interface
class Useless {
private:
int n; // number of elements
char* pc; // pointer to data
static int ct; // number of objects
void ShowObject() const;
public:
Useless();
explicit Useless(int k);
Useless(int k, char ch);
Useless(const Useless & f); // regular copy constructor
Useless(Useless && f); // move constructor
~Useless();
Useless operator (const Useless & f) const;
void ShowData() const;
};
int Useless::ct = 0;
Useless::Useless() {
ct;
n = 0;
pc =nullptr;
cout << "default constructor called; number of objects" << ct << endl;
ShowObject();
}
Useless::Useless(int k) : n(k) {
ct;
pc = new char[n];
cout << "int constructor called; number of objects: " << ct << endl;
ShowObject();
}
Useless::Useless(int k, char ch) : n(k) {
ct;
pc = new char[n];
for (int i=0; i< n; i ) {
pc[i] = ch;
}
cout <<"int, char constructor called; number of objects: " << ct << endl;
ShowObject();
}
Useless::Useless(const Useless & f) : n(f.n) {
ct;
pc = new char[n];
for (int i =0; i< n; i ) {
pc[i] = f.pc[i]; // deep copy
}
cout << "copy const called; number of objects: " << ct << endl;
ShowObject();
}
Useless::Useless(Useless && f) : n(f.n) {
ct;
pc = f.pc; // steal address (shallow copy)
f.pc = nullptr;
f.n = 0;
cout << "move const called; number of objects: " << ct << endl;
ShowObject();
}
Useless::~Useless() {
cout << "destructor called; objects left: " << --ct << endl;
cout << "deleted object:\n";
ShowObject();
delete [] pc;
}
Useless Useless::operator (const Useless & f) const {
cout << "Entering operator () \n";
Useless temp = Useless (n f.n);
for (int i=0; i < n; i ) {
temp.pc[i] = pc[i]; // copy the current object's characters
}
for (int i=n; i < temp.n; i ) {
temp.pc[i] = f.pc[i-n]; // copy the argument object's characters
}
cout << "temp object:\n";
cout << "leaving operator ()\n";
return temp;
}
void Useless::ShowObject() const {
cout << "Number of elements: " << n;
cout << "Data address: " << (void *) pc << endl;
}
void Useless::ShowData() const {
if (n==0) {
cout << "(object empty)";
}
else {
cout << "data: ";
for (int i = 0; i < n; i ) {
cout << pc[i] ;
}
}
cout << endl;
}
int main() {
Useless one (10, 'x');
Useless two = one; // call the copy constructor
Useless three(20, 'o');
Useless four(one three); // it should call operator () and then the move constructor
cout << "object one: ";
one.ShowData();
cout << "object two: ";
two.ShowData();
cout << "object three: ";
three.ShowData();
cout << "object four: ";
four.ShowData();
return 0;
}
我預計代碼會生成五個Useless物件(即物件“一”、“二”、“三”、由 operator () 函式創建的臨時物件,以及通過呼叫移動建構式創建的物件“四”)。然而,結果與我的預期不同。實際結果如下:
int, char constructor called; number of objects: 1
Number of elements: 10Data address: 0x56230b195eb0
copy const called; number of objects: 2
Number of elements: 10Data address: 0x56230b1962e0
int, char constructor called; number of objects: 3
Number of elements: 20Data address: 0x56230b196300
Entering operator ()
int constructor called; number of objects: 4
Number of elements: 30Data address: 0x56230b196320
temp object:
**leaving operator ()**
object one: data: xxxxxxxxxx
object two: data: xxxxxxxxxx
object three: data: oooooooooooooooooooo
object four: data: xxxxxxxxxxoooooooooooooooooooo
destructor called; objects left: 3
deleted object:
Number of elements: 30Data address: 0x56230b196320
destructor called; objects left: 2
deleted object:
Number of elements: 20Data address: 0x56230b196300
destructor called; objects left: 1
deleted object:
Number of elements: 10Data address: 0x56230b1962e0
destructor called; objects left: 0
deleted object:
Number of elements: 10Data address: 0x56230b195eb0
我的期望是程式通過呼叫上面定義的移動建構式生成第五個物件(物件“四”)(以“一 三”的結果作為輸入引數)。我將不勝感激任何理解結果的線索。
uj5u.com熱心網友回復:
這就是復制省略和回傳值優化。請參閱復制省略。
在 gcc/clang 中,您可以使用禁用它-fno-elide-constructors,然后您將獲得第 5 個物件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/421513.html
標籤:
上一篇:分段錯誤二叉搜索樹
