深入理解c++拷贝构造函数

本文探讨了C++中的拷贝构造函数,包括如何识别拷贝构造函数、类中是否能有多个拷贝构造函数,以及默认拷贝构造函数的行为。通过示例代码解析了拷贝构造函数的工作原理,并指出拷贝构造函数不能由成员函数模板生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 拷贝构造函数的几个细节

关键字 : c++

拷贝构造函数是 C++ 最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题 :

1.   以下函数哪个是拷贝构造函数 , 为什么 ?

1.      X::X( const  X&);   

2.      X::X(X);   

3.      X::X(X&,  int  a=1);   

4.      X::X(X&,  int  a=1, b=2);  

  2.   一个类中可以存在多于一个的拷贝构造函数吗 ?

3.   写出以下程序段的输出结果 , 并说明为什么 ?   如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。

1. #include <iostream></iostream>    

2. #include <string></string>    

3.   

4. struct  X {   

5.    template < typename  T>   

6.   X( T& ) { std::cout <<  "This is ctor."  << std::endl; }   

7.   

8.    template < typename  T>   

9.     X& operator=( T& ) { std::cout <<  "This is ctor."  << std::endl; }   

10.  };   

11.    

12.  void  main() {   

13.    X a(5);   

14.    X b(10.5);   

15.    X c = a;   

16.    c = b;   

17.  }  

 

解答如下:

1.     对于一个类 X, 如果一个构造函数的第一个参数是下列之一 :
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值 , 那么这个函数是拷贝构造函数

但是此时调用的时候,你必须显示指定,否则会有二义性。

2. X::X( const  X&);   // 是拷贝构造函数     

3. X::X(X&, int=1);  // 是拷贝构造函数   

 2. 类中可以存在超过一个拷贝构造函数

1.     class  X {      

2.     public :      

3.       X( const  X&);      

4.       X(X&);             // OK    

5.     };  

注意 , 如果一个类中只存在一个参数为 X& 的拷贝构造函数 , 那么就不能使用 const X volatile X 的对象实行拷贝初始化 .

1.     class  X {   

2.     public :   

3.       X();   

4.       X(X&);   

5.     };   

6.         

7.     const  X cx;   

8.     X x = cx;     // error    

如果一个类中没有定义拷贝构造函数 , 那么编译器会在需要的时候生成一个默认的拷贝构造函数(按位拷贝) .
这个默认的参数可能为 X::X(const X&) X::X(X&), 由编译器根据上下文决定选择哪一个 .

默认拷贝构造函数的行为如下 :
 
默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同 , 执行先父类后子类的构造 .
 
拷贝构造函数对类中每一个数据成员执行成员拷贝 (memberwise Copy) 的动作 .
 a)
如果数据成员为某一个类的实例 , 那么调用此类的拷贝构造函数 .
 b)
如果数据成员是一个数组 , 对数组的每一个执行按位拷贝 .  
 c)
如果数据成员是一个数量 , int,double, 那么调用系统内建的赋值运算符对其进行赋值 .

 

3.   拷贝构造函数不能由成员函数模版生成

1. struct  X {   

2.      template < typename  T>   

3.     X(  const  T& );     // NOT copy ctor, T can't be X    

4.   

5.      template < typename  T>   

6.     operator=(  const  T& );   // NOT copy ass't, T can't be X    

7. };   

8.   

原因很简单 , 成员函数模版并不改变语言的规则 , 而语言的规则说 , 如果程序需要一个拷贝构造函数而你没有声明它 , 那么编译器会为你自动生成一个 . 所以成员函数模版并不会阻止编译器生成拷贝构造函数 , 赋值运算符重载也遵循同样的规则 .( 参见 Effective C++ 3edition, Item45)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值