拷贝构造函数
·
目录
(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;
}
更多推荐
已为社区贡献2条内容
所有评论(0)