vm虚拟化建设网站,盐城营销型网站,大连网站设计九必选仟亿科技,保证量身定制的营销型网站1 概述 C中的大三法则是类的拷贝构造函数#xff0c;赋值运算符和析构函数这三个函数只要一个出现#xff0c;其它两个也要出现。 从C11开始引入右值引用,多了移动构造函数和移动赋值函数#xff0c;大三法则就变为大五法则。
2 大三法则 C中的大三法则是类的拷贝…1 概述 C中的大三法则是类的拷贝构造函数赋值运算符和析构函数这三个函数只要一个出现其它两个也要出现。 从C11开始引入右值引用,多了移动构造函数和移动赋值函数大三法则就变为大五法则。
2 大三法则 C中的大三法则是类的拷贝构造函数赋值运算符和析构函数这三个函数只要一个出现其它两个也要出现。 例子:
class Array
{int32_t *array_;uint32_t size_;friend std::ostream operator (std::ostream os, Array const obj);
public:Array(uint32_t n 0): array_(new int32_t[n]), size_(n){std::cout Array(int) std::endl;}Array(Array const r)//拷贝构造函数: size_(r.size_), array_(new int32_t[size_]){if(array_)memcpy(array_, r.array_, size_ * sizeof(int32_t));std::cout Array(Array const) std::endl;}Array operator(Array const r)//赋值运算符{if(this r)return *this;if(array_)delete []array_;size_ r.size_;array_ new int32_t[size_];if(array_)memcpy(array_, r.array_, size_ * sizeof(int32_t));std::cout operator(Array const) std::endl;return *this;}~Array()//析构函数{delete []array_;std::cout ~Array() std::endl;}uint32_t size() const { return size_; }bool setValue(uint32_t index, int32_t value){if(index size_)return false;array_[index] value;return true;}bool getValue(uint32_t index, int32_t value) const{if(index size_)return false;value array_[index];return true;}
};std::ostream operator (std::ostream os, Array const obj)
{for(uint32_t i 0; i obj.size_; i)os obj.array_[i] ;if(obj.size_ 0)os empty;os std::endl;return os;
}int main(int argc, char *argv[])
{Array array1(5);for(uint32_t i 0; i array1.size(); i)array1.setValue(i, i 1);Array array2 array1;Array array3;array2.setValue(3, 10);array3 array2;array3.setValue(5, 10);array3.setValue(4, 8);std::cout array1: array1 array2: array2 array3: array3;return 0;
}运行结果:
Array(int)
Array(Array const)
Array(int)
operator(Array const)
array1: 1 2 3 4 5
array2: 1 2 3 10 5
array3: 1 2 3 10 5~Array()~Array()~Array()3 大五法则 C中的大五法则是类的拷贝构造函数移动构造函数赋值运算符移动赋值函数和析构函数这五个函数只要一个出现其它四个也要出现。
给Array增加移动构造函数和移动赋值函数
class Array
{int32_t *array_;uint32_t size_;friend std::ostream operator (std::ostream os, Array const obj);
public:Array(Array r): array_(r.array_), size_(r.size_){r.array_ nullptr;r.size_ 0;}Array operator(Array r){if(this r)return *this;if(array_)delete []array_;array_ r.array_;size_ r.size_;r.array_ nullptr;r.size_ 0;return *this;}
};
int main(int argc, char *argv[])
{Array array1(5);for(uint32_t i 0; i array1.size(); i)array1.setValue(i, i 1);Array array2 array1; //拷贝构造函数Array array3;array2.setValue(3, 10);array3 array2;//赋值运算符array3.setValue(5, 10);std::cout array1: array1 array2: array2 array3: array3;Array array4 std::move(array3);//移动构造函数Array array5;array5 std::move(array2);//移动赋值函数std::cout array4: array4 array5: array5 array3: array3 array2: array2;return 0;
}运行结果:
Array(int)
Array(Array const)
Array(int)
operator(Array const)
array1: 1 2 3 4 5
array2: 1 2 3 10 5
array3: 1 2 3 10 5
Array(Array )
Array(int)
operator(Array )
array4: 1 2 3 10 5
array5: 1 2 3 10 5
array3: empty
array2: empty~Array()~Array()~Array()~Array()~Array()4 前向兼容
前面我我们为Array类型增加了移动构造函数和移动赋值函数这是C11版本才有的特性在C11之前版本没有该特性代码肯定是编译不过的。如何修改代码可以前向兼容老版本呢答案是利用宏__cplusplus。__cplusplus是C中定义的宏用来表示C的版本。
#include iostreamint main(int argc, char *argv[])
{std::cout c version: __cplusplus std::endl;return 0;
}4.1 C98
g -stdc98 test.cpp -o test
./test
c version: 1997114.2 C11
g -stdc11 test.cpp -o test
./test
c version: 2011034.3 C14
g -stdc14 test.cpp -o test
./test
c version: 2014024.4 C17
g -stdc17 test.cpp -o test
./test
c version: 2017034.5 前向兼容代码
从上面看出__cplusplus大于等201103L是C11及之后版本代码修改如下
class Array
{int32_t *array_;uint32_t size_;friend std::ostream operator (std::ostream os, Array const obj);
public:
#if __cplusplus 201103L //前向兼容Array(Array r): array_(r.array_), size_(r.size_){r.array_ nullptr;r.size_ 0;std::cout Array(Array ) std::endl;}Array operator(Array r){if(this r)return *this;if(array_)delete []array_;array_ r.array_;size_ r.size_;r.array_ nullptr;r.size_ 0;std::cout operator(Array ) std::endl;return *this;}
#endif
};
int main(int argc, char *argv[])
{Array array1(5);for(uint32_t i 0; i array1.size(); i)array1.setValue(i, i 1);Array array2 array1; //拷贝构造函数Array array3;array2.setValue(3, 10);array3 array2;//赋值运算符array3.setValue(5, 10);std::cout array1: array1 array2: array2 array3: array3;#if __cplusplus 201103L //前向兼容Array array4 std::move(array3);Array array5;array5 std::move(array2);std::cout array4: array4 array5: array5 array3: array3 array2: array2;
#endifstd::cout c version: __cplusplus std::endl;return 0;
}