copy control 复制控制
每种类型,无论是内置类型还是类类型,都对该类型对象的一组(可能为空的)操作的含义进行了定义.比如,我们可以将两个int值相加,运行vector对象的size操作,等等.这些操作定义了用给定类型的对象可以完成什么任务.
复制构造函数,赋值操作符和析构函数总称为复制控制(copy control).
编译器自动实现这些操作,但类也可以定义自己的版本.
复制构造函数:
直接初始化 和 复制初始化.
string null_book = "9-99-99999-9";// copy-initialization
string dots(10,'.'); // direct-initializaton
string empty_copy=string(); // copy-initialization
string empty_direct; // direct-initialization
合成的复制构造函数
如果我们没有定义复制构造函数,编译器会给我们合成一个.与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数.合成复制构造函数(synthesized copy constructor)的行为是,执行逐个成员初始化(memberwise initialize),将新对象初始化为原对象的副本.
所谓"逐个成员",指的是编译器将现有对象的每个非static成员,依次复制到正创建的对象.只有一个例外,每个成员的类型决定了复制该成员的含义.
合成复制构造函数直接复制内置类型成员的值.
类类型成员使用该类的复制构造函数进行复制.
数组成员的复制是个例外,虽然一般不能复制数组,但如果一个类具有数组成员,则合成复制函数将复制数组.复制数组时合成复制构造函数将复制数组的每一个元素.
Sales_item :: Sales_item(const Sales_item &rhs): isbm( rhs.isbn ), //calls string copy constructor units_sold ( rhs.units_sold), //copy rhs.units_sold revenue (rhs.revenue) { }
禁止复制,类必须显式声明其复制构造函数为private.
合成赋值操作符(synthesized assignment operator),与合成复制构造函数类似.它会逐个成员赋值 (memberwise assignment).
e.g. Sales_item的合成赋值操作符可能如下所示:
//equivalent to the synthesized assignment operator Sales_item & Sales_item::operator = (const Sales_item & rhs){ isbm = rhs.isbn;//calls string::operator = units_sold = rhs.units_sold; //use built-in int assignment revenue =rhs.revenue; return *this; }
demo:
#include <iostream> #include <string> using namespace std; class my_class{ public: int a; string s; char ch[10]; void to_s(){ cout<<"a address:"<<&a<<",a val:"<< a<<","<<endl <<"s address:"<<&s<<",s val:"<<s<<"," <<endl <<"ch address:"<<&ch<<",ch val:"<<ch<<endl; } }; int main() { my_class obj; obj.a=10; obj.s="danniswu吴"; obj.ch={'h','e','l','\0'}; obj.to_s(); my_class obj2(obj); obj2.to_s(); return 0; }
如果类需要析构函数,则它也需要赋值操作符和复制构造函数,这是一个有用的经验法则.这个规则常称为 三法则(rule of three), 指的是如果需要析构函数,则需要所有这三个复制控制成员.