示例代码:
#include <iostream>
using namespace std;
class Array2D {
private:
int m,n; // m rows, n cols
int *array;
public:
Array2D(int _m, int _n):m(_m), n(_n) {
cout << "ctor" << endl;
array = new int[m*n];
}
Array2D(const Array2D &a) {
cout << "copy ctor" << endl;
int j,k;
m = a.m;
n = a.n;
array = new int[m*n];
for(int i = 0; i < m*n; ++i) {
k = i % a.n;
j = (i - k) /n;
array[i] = a(j, k);
}
}
Array2D(Array2D &&a) noexcept {
cout << "move ctor" << endl;
m = a.m;
n = a.n;
array = a.array;
a.array = nullptr;
}
~Array2D() {
delete[] array;
cout << "dtor" << endl;
}
int& operator()(int x, int y) {
return array[x*n+y];
}
const int& operator()(int x, int y) const {
return array[x*n+y];
}
Array2D& operator=(const Array2D &a) {
cout << "call operator=" << endl;
if (this->array != a.array) {
int j,k;
this->m = a.m;
this->n = a.n;
delete[] this->array;
this->array = new int[m*n];
for(int i = 0; i < m*n; ++i) {
k = i % a.n;
j = (i - k) /n;
this->array[i] = a(j, k); //calling: const int& operator()(int x, int y) const
}
}
return *this;
}
Array2D& operator=(Array2D &&a) {
cout << "call move operator=" << endl;
m = a.m;
n = a.n;
array = a.array;
a.array = nullptr;
return *this;
}
};
Array2D getArray2D() {
cout << "in getArray2D()" << endl;
Array2D a2d(1000,1000);
a2d(100,100) = 100;
a2d(200,200) = 200;
a2d(900,900) = 900;
return a2d;
}
(1)main中的测试代码:
Array2D big1 = getArray2D();
cout << big1(100,100) << " " << big1(200,200) << " " << big1(900,900) << endl;
C++98 | C++11 & C++14 | C++17 & C++20 | |||
With -fno-elide-constructors | in getArray2D() ctor copy ctor dtor copy ctor dtor 100 200 900 dtor | in getArray2D() ctor move ctor dtor move ctor dtor 100 200 900 dtor | in getArray2D() ctor move ctor dtor 100 200 900 dtor | ||
Without -fno-elide-constructors | in getArray2D() ctor 100 200 900 dtor |
(2)main中的测试代码:
Array2D big3(1,1);
big3 = getArray2D();
cout << big3(100,100) << " " << big3(200,200) << " " << big3(900,900) << endl;
C++98 | C++11 & C++14 & C++17 & C++20 | ||||
With -fno-elide-constructors | ctor in getArray2D() ctor copy ctor dtor call operator= dtor 100 200 900 dtor | ctor in getArray2D() ctor move ctor dtor call move operator= dtor 100 200 900 dtor | |||
Without -fno-elide-constructors | tor in getArray2D() ctor call operator= dtor 100 200 900 dtor | ctor in getArray2D() ctor call move operator= dtor 100 200 900 dtor |
说明:使用C++98标准编译时,需要注释掉移动构造函数和移动赋值函数
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary that is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.
默认情况下,不带-fno-elide-constructors选项,编译器会进行良好的优化。