C++ 中类的构造函数理解(二)
写在前面
上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索。主要是复制构造函数的使用。
复制构造函数
复制构造函数也称拷贝构造函数,它只有单个形参,且该形参是对本类类型对象的引用。其作用有以下几点:
1、根据另一个同类型的对象显示或隐式初始化一个对象
2、复制一个对象,将它作为实参传递给一个函数
3、从函数返回时复制一个对象
4、初始化顺序容器中的元素
5、根据元素初始化列表初始化数组元素
编译器合成的复制构造函数
如同默认构造函数一样,如果我们没有显示地定义复制构造函数,编译器将为我们合成一个复制构造函数。合成复制构造函数将新对象初始化为原对象的副本。编译器对每个数据成员进行注意初始化。合成复制构造函数直接复制内置类型成员的值,对于类类型的成员,则使用该类的复制构造函数进行复制。如果某个类包含数组类型的成员,那么合成复制构造函数将复制数组的每个元素。
测试代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
class myClass{
public:
myClass(int i1, char c1)//普通构造函数
{
a = i1;
c = c1;
}
int a;
char c;
};
int main()
{
myClass class1(1, 'a');
myClass class2( class1);//调用合成的复制构造函数
cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;
system("pause");
return 0;
}
运行结果如下:
class1中的成员都被复制到了class2中。合成复制构造函数使用的是浅拷贝的策略。也就是说,如果class1中有指针类型的成员,那么使用合成的复制构造函数时,class2中对应的那个指针与class1中的指针指向的是同一片地址。
自定义的复制构造函数
自己定义复制构造函数时,可将复制构造函数的参数设置为类类型的引用,通常用const修饰参数。尽管也可以接受非const引用的复制构造函数。
测试代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
class myClass{
public:
myClass(int i1, char c1)//普通构造函数
{
a = i1;
c = c1;
}
myClass( const myClass& myclass)//复制构造函数
{
}
int a;
char c;
};
int main()
{
myClass class1(1, 'a');
myClass class2( class1);//调用自定义的复制构造函数
cout<<"class1 is: "<<class1.a<<" "<<class1.c<<endl;
cout<<"class2 is: "<<class2.a<<" "<<class2.c<<endl;
system("pause");
return 0;
}
上述代码自定义了拷贝构造函数,尽管自定义的复制构造函数函数体为空,但这时系统不再合成复制构造函数,而是调用用户自定义的,此时的运行结果如下:
由于自定义复制构造函数函数体为空,因此没有完成复制。
修改复制构造函如下:
myClass( const myClass& myclass)
{
this->a = myclass.a;
this->c = myclass.c;
}
我们可以让自定义的复制构造函数在复制时采用深拷贝的方式。此外,当没有对当前的类重载运行符”=“时,下面这句话也是调用复制构造函数:
myClass class3 = class1;
总结
这篇笔记写得有点匆忙,之后有时间需要进一步完善。