C++拷贝构造
拷贝构造是一种特殊的构造函数, 用自身这种类型来构造自身
用户未定义拷贝构造,系统默认提供一个隐式的拷贝构造,它会将已存在于对象中的数据成员逐个的拷贝到新创建的对象中(浅拷贝)
拷贝构造:类名
(const 类名&
引用名);
如果类中又动态申请内存,必须要重写拷贝构造,来做深拷贝
拷贝构造的调用情况:
1、用一个类对象去初始化该类的另一个对象时
2、如果函数的形参是类的对象,调用函数时进行实参传递时,调用拷贝构造
3、如果一个函数的返回值是类对象,函数调用返回时
拷贝构造:用自身这种类型来构造自身,是一种特殊的构造
class A
{
public:
A(){}//无参构造(默认构造)
A(int a){}//有参构造
A(const A &CA){}//拷贝构造 在这个里面把传进来的对象一一赋值给新的对象
};
浅拷贝:没有给新的指针申请内存来存内容,新的对象里面的指针和传进的指针都是指向同一块内存
这样操作之后,在最后释放内存的时候,对象A的指针的内存被释放之后,就相当于对象B的也被释放了,对象B的指针没有内存可以释放。如果在是使用中,释放了对象A的指针内存,那么同样对象B的也被释放了,那么对象B里面的指针就没有了内存
深拷贝:给行的指针申请内存来存内存,这样就不会出现浅拷贝所出现的问题了
这样每个对象使用的都是自己的内存,对象A被释放,那么这里并不会影响到对象B,这里的深拷贝是需要自己将已存在于对象中的数据成员逐个的拷贝到新创建的对象中,指针就申请内存来赋值
类里的数据成员初始化:
1、成员列表的初始化在一些特殊的情况下z,数据成员的初始化只能用初始化列表,不能直接赋值
2、必须写在构造函数的定义后面,用:表示,如果用对各成员用逗号隔开
3、构造函数能对数据进行的操作,初始化列表也都可以
4、初始化列表里面的每一个项里面为构造
1、成员初始化列表要写在构造函数的定义后面
2、成员初始化列表只能构造成员,只能在这个表里面调用构造
3、构造函数是函数,函数体可以调用其它函数
示例:
class
A
{
public:
A(int x, int y, int z) :a(x),
b(y),c(z){}//第一种初始化列表的使用,和构造之直接赋值一样效果
/*A(int x, int y, int z)
{
a =
x;
b = y;
z = y;
}*/
int a, b, c;
};
//如果类里面有const成员变量必须要用初始化列表
class A
{
public:
A(int x, int y)
:a(x), b(y){}
/*A(int x, int y)
{
a = x;
b =
y;
}*///这种方式赋值是不可以给const成员变量赋值的
int a;
const int b;
};
//成员变量或基类未声明默认构造函数
class A
{
public:
A(int x, int y, int z)
:a(x), b(y), c(z){}
int a;
int b;
int c;
};
class
B
{
public:
B(int x,int y,int z):a(x,y,z){}//初始化列表
A
a;//A类作为B类的成员
};
//数据成员按照他们在类中的声明顺序来初始化,而不是按照在初始化列表中出现的顺序。
class
A
{
public:
A(int x, int y, int z) :a(x), b(y), c(z){ cout <<
"A" << endl; }
int a;
int b;
int c;
};
class
B
{
public:
B(int x, int y, int z) :aa(x, y, z), a(x, y, z){ cout
<< "B" << endl; }//初始化列表
A a;
A aa;
};
class
C
{
public:
C():a(0,0,0),b(0,0,0){}
B b;
A a;
};