拷贝构造函数

目录

一、基本类型的赋值  

二、c++两种初始区别

三、复制构造函数的基本概念

四、复制构造函数起作用的三种情况

(1)当用一个对象去初始化同类的另一个对象时 

(2)如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用

(3)如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用


一、基本类型的赋值  

   int a=4;
   int b=a;

二、c++两种初始区别

   1.对于基本类型没有区别
    拷贝初始化 int a=5; 
    直接初始化 int a(5) 
   2.对于类类型
   直接初始化直接调用实参匹配的构造函数
   例如:
   A x(2);//直接初始化,调用构造函数 
   拷贝初始化总是调用拷贝构造函数   
   A y=x;//拷贝初始化,调用拷贝构造函数,

三、复制构造函数的基本概念

  • 只有一个参数,即对同类对象的引用
  • 形如 X:X(X&)或者X::X(const X &),二者选一,后者能以常量对象作为参数
  • 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能  
代码举例: 关于调用默认的复制构造函数 
#include <iostream>
using namespace std;
class A
{
	int id;
public: 
	A(int i){
		id = i;
		cout<<id<<"--->构造函数"<<endl;	
	}	
	~A(){	
		cout<<id<<"--->析构函数"<<endl;	
	}	
}; 
int main(){
    A a(3);
    A b = a;
	cout<<"end of main"<<endl;
    return 0;
}
代码举例2:关于自己定义的复制构造函数 
class complex
{
	public:
	  double real,imag;
	  complex()
	  {
	  	
	   } 
	  complex(const complex & c)//自己定义了一个复制构造函数 
	  {
	  	real=c.real;
	  	imag=c.imag;
	  	cout<<"复制构造函数"; 
	   } 
}; 
complex c1;
complex c2(c1); 
 完成 

四、复制构造函数起作用的三种情况

(1)当用一个对象去初始化同类的另一个对象时 

   complex c2(c1);
   complex c2=c1;//初始化语句,非赋值语句
#include<iostream>
using namespace std;
class complex
{
	public:
	  double real,imag;
	  complex(double x,double y)//定义了一个构造函数 
	  {
	  	real=x;
	  	imag=y;
	   } 
	  complex(const complex & c)//定义了一个复制构造函数 
	  {
	  	real=c.real; 
	  	imag=c.imag;
	  	cout<<real<<" "<<imag<<endl;
	  	cout<<"复制构造函数"<<endl; 
	   } 
}; 
int main()
{
	complex c1(1.2,3.6);
	complex c2(c1);//这两种初始化方式等价 
	complex c3=c1;
	cout<<"end"; 
	return 0; 
}

(2)如果某函数有一个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用

class A
{
	public:
	A()
	{
	 } ;
	 A(A & a)//该复制构造函数并没有做复制的工作,这个形参就未必是实参的拷贝 
	 {
	 	cout<<"复制构造函数"
	  } 
 } 
void fun(A a1)//函数fun()的参数a1是对象类型的 
//如果一个函数的参数是对象,就一定会用复制构造函数初始化,
//用复制构造函数初始化的时候,复制构造函数的参数是实参a2,就意味a1是a2的复制品 
{
} 
int main()
{
	A a2;
	fun(a2);
	return 0;
  }  
代码举例:
#include <iostream>
using namespace std;
class Line{
   public:
      int getLength( void );
      Line( int len );            
      Line( const Line &obj);     
      ~Line();                  
   private:
      int *ptr;
};
Line::Line(int len){
    cout << "调用构造函数" << endl;
    ptr = new int;
    *ptr = len; //将len放入指针ptr指向的内存空间 
}
Line::Line(const Line &obj){
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new int;
    *ptr = *obj.ptr; 
}
Line::~Line(){
    cout << "释放内存" << endl;
    delete ptr;
}
int Line::getLength(  ){
    return *ptr;
}
void display(Line obj)//display函数要求一个类类型的参数,然后将之前定义的参数line传递进去,注意,在传递进去的过程会发生形参到实参的复制,此时会调用拷贝构造函数, 
{
   cout << "line 大小 : " << obj.getLength() <<endl;//在执行display函数体的时候,调用getlength函数输出line大小
}
int main( ){
	Line line(10);
	display(line);//调用display函数 
	return 0;//这之后程序会进行析构,第一个析构,是display函数里面的形参,对于display函数中的obj来说,作用范围仅仅在display函数内部,出display函数后肯定进行析构 
}//第二个析构是int main()中定义的line对象的析构

(3)如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用

class A
{
	public:
	int v;
	A(int n)
	{
		v=n;
	 } ;
	 A(const A & a)//定义了复制构造函数 
	 {
	 	v=a.v;
	 	cout<<"复制构造函数"; 
	  } 
 } ;
A fun()//表示fun()函数的返回值是类A的对象
//根据c++的规定一个函数的返回值如果是对象,这个对象用复制构造函数初始化 
{
	A b(4);
	return b; 
 } 
int main()
{
	cout<<fun().v<<endl;
	return 0;
 } 
代码举例:
#include<iostream>
using namespace std;
class point
{		int x,y;
	public:
		point(int a=0,int b=0){x=a;y=b;}
		point(point &p);
		int getx(){return x;}
		int gety(){return y;}
		~point(){cout<<"析构"<<endl;}
};
point::point(point &p)
{
	x=p.x+10;  y=p.y+20;
	cout<<"调用复制构造函数"<<endl;
}
void f(point p)
{
   cout<<p.getx()<<" "<<p.gety()<<endl;
   }
point g()
{
  point q(3,5);
  return q;
}
int main(){
	point p1(1.1,2.2);//定义了一个对象p1同时调用构造函数 
	point p2(p1);//用p1初始化p2,要调用复制构造函数 
	cout<<p2.getx()<<" "<<p2.gety()<<endl;
	f(p2);//调用函数f(),f()函数的参数是类类型的,实参到形参的传递会调用拷贝构造函数,紧接着执行函数体,输出p.getx(),p.gety() ,当函数f()结束时,参数p是局部对象
	//它要进行析构 
	p2=g();//调用g()函数,g()函数返回的是一个类类型,在这个过程中会调用拷贝构造函数(从结果中并没有看出它调用了拷贝构造函数),当执行g()的函数体的时候,创建一个q,并且把q返回,在这个过程中会产生临时对象,
	//当g()函数结束的时候,会调用析构函数,清理调它 
	cout<<p2.getx()<<" "<<p2.gety()<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值