| 
			
	
	
		
		
				拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:
		 
				
						1. 以下函数哪个是拷贝构造函数,为什么?
		 
				
						
								
										
												X::X(
												const
												 X&);   
										
								
										X::X(X);   
								
										X::X(X&, 
										int
										 a=1);   
								
										X::X(X&, 
										int
										 a=1, b=2);  
								  2. 一个类中可以存在多于一个的拷贝构造函数吗? 
						
								3. 写出以下程序段的输出结果, 并说明为什么?
						
						
						如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。
				 
								
										
												
														
																#include <iostream></iostream> 
																  
														
												
														
																#include <string></string> 
																  
														
												
														  
												
														
																struct
																 X {   
														
												
														  
														template
														<
														typename
														 T>   
												
														  X( T& ) { std::cout << 
														"This is ctor."
														 << std::endl; }   
												
														  
												
														  
														template
														<
														typename
														 T>   
												
														    X& operator=( T& ) { std::cout << 
														"This is ctor."
														 << std::endl; }   
												
														};   
												
														  
												
														
																void
																 main() {   
														
												
														  X a(5);   
												
														  X b(10.5);   
												
														  X c = a;   
												
														  c = b;   
												
														}  
												   
										解答如下:
								 
										1. 
										对于一个类X,如果一个构造函数的第一个参数是下列之一:a) X&
 b) 
const X&
 c) volatile X&
 d) const volatile 
X&
 且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.
 
										
												
														
																
																		
																				X::X(
																				const
																				 X&);  
																				
																				  
																		
																
														
																
																		X::X(X&, 
																		int
																		=1); 
																		
																		  
																
														  2.类中可以存在超过一个拷贝构造函数,  
												
														
																
																		
																				class
																				
																						 X {    
  
																				
																		
																		
																		
																
																		
																				public
																				
																						:      
																				
																		
																
																		
																				  X(
																				const
																				 X&);      
																		
																
																		
																				  X(X&);            
																				
																				  
																		
																
																		
																				};  
																		
																 注意,如果一个类中只存在一个参数为X&的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化. 
														
																
																		
																				
																						class
																						
																								 X { 
  
																						
																				
																				
																				
																		
																				
																						public
																						
																								:   
																						
																				
																		
																				
																						  X();   
																				
																		
																				
																						  X(X&);   
																				
																		
																				
																						};   
																				
																		
																				
																						    
																				
																		
																				
																						const
																						
																								 X cx; 
  
																						
																				
																		
																				
																						X x = cx;    
																						
																						  因为cx是const类型的,必须要用const X&类型的拷贝构造函数来执行拷贝,它担心会被修改!
																				
																		 如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数.这个默认的参数可能为X::X(const 
X&)或X::X(X&),由编译器根据上下文决定选择哪一个.
 
																				默认拷贝构造函数的行为如下:默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造.
 拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise 
Copy)的动作.
 a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数.
 b)如果数据成员是一个数组,对数组的每一个执行按位拷贝.
 c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值.
 
																				
																						 
																				
																		 
																						
																								3.  拷贝构造函数不能由成员函数模版生成.  
																		
																				
																						
																								
																										
																												
																														struct
																														
																																 X { 
  
																														
																												
																												
																												
																										
																												
																														    
																														template
																														<
																														typename
																														 T>   
																												
																										
																												
																														    X( 
																														const
																														 T& );    
																														
																														  
																												
																										
																												
																														  
																												
																										
																												
																														    
																														template
																														<
																														typename
																														 T>   
																												
																										
																												
																														    operator=( 
																														const
																														 T& );  
																														
																														  
																												
																										
																												
																														};   
																												
																										
																												
																														  
																												
																										 原因很简单, 成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没有声明它,那么编译器会为你自动生成一个. 
所以成员函数模版并不会阻止编译器生成拷贝构造函数, 赋值运算符重载也遵循同样的规则.(参见Effective C++ 3edition, Item45)
   
	    
    
 |