练习13.1:
如果构造函数的第一个参数是自身类类型的引用,且所有其他参数(如果有的话)都有默认值,则此构造函数是拷贝构造函数。拷贝构造函数在以下几种情况下会被使用:
●拷贝初始化(用=定义变量)。
●将一个对象作为实参传递给非引用类型的形参。
●一个返回类型为非引用类型的函数返回一个对象。
●用花括号列表初始化一个数组中的元素或一个聚合类中的成员。
●初始化标准库容器或调用其insert/push操作时,容器会对其元素进行拷贝初始化。
练习13.2:
这一声明是非法的。因为对于上一题所述的情况,我们需要调用拷贝构造函数,但调用永远也不会成功。因为其自身的参数也是非引用类型,为了调用它,必须拷贝其实参,而为了拷贝实参,又需要调用拷贝构造函数,也就是其自身,从而造成死循环。
练习13.3:
这两个类都为定义拷贝构造函数,因此编译器为它们定义了合成的拷贝构造函数。合成的拷贝构造函数逐个拷贝非const成员,对内置类型的成员,直接进行内存拷贝,对类类型的成员,调用其拷贝构造函数进行拷贝。
因此,拷贝一个StrBlob时,拷贝其唯一的成员data,使用shared_ptr的拷贝构造函数来进行拷贝,因此其引用计数增加1。
拷贝一个StrBlobPtr时,拷贝成员wptr,用weak_ptr的拷贝构造函数进行拷贝,引用计数不变,然后拷贝curr,直接进行内存复制。
练习13.4:
练习13.5:
HasPtr::HasPtr(const HasPtr &hp)
{ps = new string(*hp.ps);//拷贝ps指向的对象,而不是拷贝指针本身i = hp.i;
}