深拷贝有独立的资源,浅拷贝拷贝的是指针。
#include
#include
#include
using namespace std;
class ValueLikeClass
{
public:
//原来构造函数也可以有默认实参,默认实参除了字面值常量
//原来在函数体做的初始化操作都可以放到初始化参数列表中做
//拷贝构造居然可以也在参数化列表里完成虽然看上去不怎么好看
ValueLikeClass(const string& s = string()) :ps(new string(s)), i(0) {}
ValueLikeClass(const ValueLikeClass& p) :ps(new string(*p.ps)), i(p.i) {}
ValueLikeClass& operator=(const ValueLikeClass&);
~ValueLikeClass() { delete ps; }
private:
std::string* ps;
int i;
};
ValueLikeClass& ValueLikeClass::operator=(const ValueLikeClass& rhs)
{
auto newp = new string(*rhs.ps);//首先开辟新的存储空间并用右值对象完成初始化
delete ps;//注意这儿记得释放右值对象的资源,为了防止自我拷贝出错,注意一定要在拷贝完之后delete指针左侧运算符
//否则,当自身拷贝就会出现问题
ps = newp;//正常初始化坐值成员
i = rhs.i;//同上
return *this;//返回类本身
}
class PointerLikeClassWithSmartPoiter
{
public:
PointerLikeClassWithSmartPoiter(const string &s = string()):sps(make_shared(s)) {}
PointerLikeClassWithSmartPoiter(const PointerLikeClassWithSmartPoiter& m) :sps(m.sps){}
PointerLikeClassWithSmartPoiter& operator=(const PointerLikeClassWithSmartPoiter& m) { sps = m.sps; }
private:
shared_ptr sps;
};
class PointerLikeClassDirect
{
public:
PointerLikeClassDirect(const string& s = string()) :ps(new string(s)), i(0), use(new size_t) {}
PointerLikeClassDirect(const PointerLikeClassDirect& m) :ps(m.ps), i(m.i), use(m.use) { (*use)++; }
PointerLikeClassDirect& operator=(const PointerLikeClassDirect& m);
~PointerLikeClassDirect();
private:
int i; //整数成员
size_t* use; //资源引用计数
string* ps; //管理资源的指针
};
PointerLikeClassDirect& PointerLikeClassDirect::operator=(const PointerLikeClassDirect& m)
{
(*m.use)++;//右侧增加
if (*--use == 0)//左侧递减,若为零则释放
{
delete ps;
delete use;
}
ps = m.ps;
i = m.i;
*use = *m.use;
return *this;
}
PointerLikeClassDirect::~PointerLikeClassDirect()
{
if (-- * use==0)
{
delete ps;
delete use;
}
}