C++笔记二:复制构造函数总结

       复制构造函数(copy constructor

       C++允许用一个对象初始化另一个对象。完成这个任务的叫复制构造函数。

 

       复制构造函数的调用时机

  •              用同类型的对象显式或隐式初始化一个对象。(包括复制初始化和直接初始化)
  •        将一个类对象作为实参传递给一个函数。(非引用类型参数。)
  •        从函数返回一个对象。
  •        初始化顺序容器中的元素。
  •        根据元素初始化式列表初始化数组元素。

      1.对象的初始化

      C++支持两种形式的初始化:直接初始化和复制初始化。复制初始化用=符号,直接初始化将初始化式放在圆括号中。

       直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定的构造函数创建一个临时对象,然后复制构造函数将临时对象复制到正在创建的对象。

string str = "hello world";		//复制初始化
string str2("hello");			//直接初始化
string empty_copy = string();	//复制初始化,有=号的都是复制初始化
Class obj1 = obj2;              //复制初始化
string empty_direct;			//直接初始化


          2.形参与返回值

       当形参不是引用类型时,将采用值传递。类似的以非引用类型作返回值时,将返回return语句中值的副本。当形参或返回值为类类型时,都将导致复制构造函数的调用。

 

       编译器合成的复制构造函数

       如果我们定义类时没有定义复制构造函数,就像如果我们没有定义构造函数一样,编译器将为我们合成一个默认的复制构造函数。

        合成的复制构造函数的行为是一次逐个的将现有对象的非static成员的值复制给正在创建的对象。对于只包含简单内置类型(不含指针成员变量)的类来说这是对的。但如果类有指针成员变量,那你就要小心了。最好自己提供复制构造函数。

        复制构造函数只是简单的复制值,遇到指针也是如此。意思是这会导致两个对象的指针成员变量指向同一块内存。这几乎总是错误的。

                               

 

             如果类中有指针成员变量,最好自己定义复制构造函数。

 

        自定义复制构造函数

              复制构造函数就是接受单个类类型引用形参的构造函数。(不定义为引用会导致无限递归)然后自己在复制构造函数中实现各个成员变量的复制。遇到指针成员变量,该另外new内存的就另外new。

class Foo
{
public:
	Foo();			//构造函数
	Foo(const Foo&);//复制构造函数
};


 

            禁止复制

      有些类需要完全禁止复制。例如iostream类就不允许复制。

       为了防止复制,必须自己显示声明复制构造函数并声明为private。这样用户代码就不允许复制该类类型的对象,编译器将拒绝任何复制的尝试。(编译时错误)

       但是类的友元很成员函数还是可以复制。如果连这也想禁止的话,可以显示声明复制构造函数为private但不现实它。声明而不定义成员函数是合法的。但是,使用未定义的成员将导致链接失败。(链接时错误)。不使用就没错。

 

           特别注意:

       根据构造函数的规则:如果你定义了自己的构造函数(包括复制构造函数),编译器将不再提供默认构造函数。这意味着定义复制构造函数之前必须定义默认构造函数

 

             建议:最好显示的一起定义默认构造函数和复制构造函数。不定义复制构造函数和复制构造函数的类或造成严重的使用局限性。不允许复制的类对象只能作为引用传递给函数或从函数返回,也不能用在容器的元素。

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值