复制控制
复制控制包括复制/拷贝构造函数、赋值操作符、析构函数
1.复制/拷贝构造函数(copy constructor) - 控制复制
接受单个本类类型对象的引用形参(常用const修饰)
作用:
1.根据另一个同类型的对象显式或隐式初始化一个对象//使用的是copy-initialization → =
eg:
string nullBook="9-999-99999-9"/string();
2.形参或者返回值是类类型时由其复制
eg:
string makePlural(size_t, const string &, const string &)//因为形参是引用,所以不用复制构造函数,而返回值用复制构造函数
4.初始化顺序容器中的元素
5.根据元素初始化列表初始化数组元素
合成的复制构造函数
如果不自定义复制构造函数就会自动生成一个,除了static成员外,都会逐个成员初始化,包括数组的每一元素
eg:
SalesItem::SalesItem(const SalesItem &orig):_isbn(orig._isbn),_unitsSold(orig._unitsSold),r_evenue(orig.revenue){}
自定义复制构造函数
一般需要使用的情况:
有数据成员是指针、成员需要在构造函数中分配其他资源
禁止复制
声明复制构造函数为private,比如io类不允许复制
关于浅拷贝和深拷贝
如不打算共享指针、打开文件、占有硬设备(例如打印机)服务需要深拷贝
eg://不打算共享指针
class Test
{
public:
Test(char *pN)
{
cout <<"Constructing "<<pN<<endl;
_pChar=new char(strlen(pN)+1);
if (_pChar!=0)
{
strcpy(_pChar,pN);
}
}
Test(Test& p)
{
cout<<"copying "<<p._pChar<<endl;
_pChar=new char [strlen(p._pChar)+1];
if (_pChar!=0)
strcpy(_pChar,p._pChar);
}
~Test()
{
cout<<"Destructing "<<_pChar<<endl;
delete [] _pChar;
}
private:
char *_pChar;
};
2.赋值操作符(assignment operator) - 赋值
eg:
SalesItem item1,item2;
item1=item2;
SalesItem& operator=(const SalesItem &);
合成的赋值操作符
SalesItem& SalesItem::operator=(const SalesItem &rhs)
{
_isbn=rhs._isbn;
_unitsSold=rhs._unitsSold;
_evenue=rhs.revenue;
return *this;
}
tips:
复制构造函数和赋值操作符之间的区别
SalesItem::SalesItem(const SalesItem &orig)
SalesItem& SalesItem::operator=(const SalesItem &rhs)
复制构造函数见其前面的作用小节
赋值操作符是存在的对象之间赋值
3.析构函数(destructor) - 撤销对象时执行
eg:
SalesItem *p=new SalesItem;
delete p;//new出来的这时才会调用析构函数
SalesItem *p=new SalesItem[10];
delete [] p;//会逆序从 size()-1到0的调用析构函数
合成析构函数//不管自定义与否都会自动生成并运行
与构造函数中声明的数据成员相反,逆序撤消每一个非static成员
三法则
如果需要析构函数,则需要复制构造函数和赋值操作符