#include<string>
#include<iostream>
// 行为像值的类
class HasPtr{
public:
friend void swap( HasPtr& lhp, HasPtr& rhp);
HasPtr( const std::string &s = std::string()):
ps( new std::string( s)), num( 0) {
std::cout << "constructor" << std::endl;
}
HasPtr( const HasPtr& hp):
ps( new std::string( *( hp.ps))), num( hp.num) {
std::cout << "copy constructor" << std::endl;
}
// 类值拷贝赋值运算符,通常组合了析构和构造函数的操作
// 如果将一个对象赋予它自身,赋值运算符必须能正确工作
// HasPtr& operator=( const HasPtr& hp){
// num = hp.num;
// auto newp = new std::string( *( hp.ps));
// delete ps;
// ps = newp; // ps = new std::string( *( hp.ps)); 错误写法,如果 hp 和 *this是同一个对象,上面的 delete 释放了指向的内存
// std::cout << "operator=" << std::endl;
// return *this;
// }
// //使用 swap 的赋值运算符,多一次拷贝构造和析构,但可以有效防止自赋值异常
HasPtr& operator=( HasPtr hp){
std::cout << "swap operator=" << std::endl;
swap( *this, hp);
return *this;
}
~HasPtr(){
std::cout << "destructor" << std::endl;
delete ps;
}
private:
int num;
std::string *ps;
};
// 写法一:std::swap()
// 写法二:using std::swap
// 第一种指定使用标准库算法,第二种写法会在类型自带的算法与标准库的算法进行函数匹配
inline void swap( HasPtr& lhp, HasPtr& rhp){
std::swap( lhp.ps, rhp.ps);
std::swap( lhp.num, rhp.num);
std::cout << "HasPtr friend swap" << std::endl;
}
// // 行为像指针的类
// class HasPtr{
// public:
// HasPtr( const std::string &s = std::string()):
// ps( new std::string( s)), num( 0), cnt( new std::size_t( 1)) {}
// HasPtr( const HasPtr& p):
// ps( p.ps), num( p.num), cnt( p.cnt) { ++*cnt;}
// HasPtr& operator=( const HasPtr& hp){
// ++*hp.cnt;
// if( --*cnt == 0){
// delete ps;
// delete cnt;
// }
// ps = hp.ps;
// num = hp.num;
// cnt = hp.cnt;
// return *this;
// }
// ~HasPtr(){
// if( --*cnt == 0){
// delete ps;
// delete cnt;
// }
// }
// private:
// std::string *ps;
// int num;
// std::size_t *cnt;
// };
int main(){
HasPtr hp("hello");
std::cout << "******************" << std::endl;
HasPtr hp2(hp);
std::cout << "******************" << std::endl;
HasPtr hp3;
std::cout << "******************" << std::endl;
hp3 = hp;
std::cout << "******************" << std::endl;
using std::swap;
swap(hp, hp3);
std::cout << "******************" << std::endl;
// 使用 swap 版 operator 的输出:
// constructor
// ******************
// copy constructor
// ******************
// constructor
// ******************
// copy constructor
// swap operator=
// HasPtr friend swap
// destructor
// ******************
// HasPtr friend swap
// ******************
// destructor
// destructor
// destructor
//使用引用参数的operator=输出:
// constructor
// ******************
// copy constructor
// ******************
// constructor
// ******************
// operator=
// ******************
// HasPtr friend swap
// ******************
// destructor
// destructor
// destructor
return 1;
}
c++ primer(第五版)笔记 第十三章(2) 拷贝控制
最新推荐文章于 2023-08-11 14:23:04 发布