构造函数
构造析构
一、构造函数
1、介绍
构造函数,它是一种特殊的函数,主要用来在创建对象时初始化对象,即为对象的成员变量赋初始值。
2、构造函数的定义:
//1 构造函数名和类名相同
//2 构造函数没有返回值类型,和返回值
//3 构造函数可以重载,需要满足函数重载的条件
class student
{
public:
student(){} //无参构造(默认构造)
student(int a){} //有参构造(带参构造)
};
3、构造函数的调用时机
//1 在创建一个新的对象的时候会调用
//调用无参构造
student stu;
student *p = new student;
//调用带参构造
student stu(1);
student *p = new student(1);
4、构造函数的特点
/*
* 1 如果一个类中没有显示的给出构造函数,系统会自动给出一个缺省的(隐式)什么都不干的构造函数
* 2 如果类中有多个构造函数,那么通常会有不同的参数列表和函数体
* 3 如果用户提供了无参(带参)构造,那么系统就不再提供默认构造
* 4 类中如果只有带参构造,没有无参构造,那么就不能调用默认构造的方式初始化对象,想用这种方式初始化对象就要提供无参构造
*
*
*/
5、拷贝构造(一种特殊的构造)
//1 拷贝构造是一种特殊的构造函数,用自身这种类型来构造自身
//例;
student stu1;
student stu2 = sut1;//在这一句就会调用拷贝构造
拷贝构造的定义:
1 没有写拷贝构造,系统会提供一个隐式的拷贝构造,而这个拷贝构造的操作,我们可以理解为,是用 ‘ = ’ 号一个一个的将存在于对象中的数据成员赋值给新创建的对象中。
// 2 自定义拷贝构造
// 类名(const 类名& 引用名){}
// 这里的const不加也可以,但是这里是拷贝,也就是复制的意思,所以加上,防止被改
// 在函数体里面通常的做法是逐一拷贝传进来的对象的成员,赋值给新的对象,当然也可以自己定义内容
//例:
class Student
{
int id;
public:
Student(const Student&stu)
{
this->id=stu.id;
//把传进来对象的id赋值给当前调用对象的id
}
}
拷贝构造的调用:
//1 在用同种类的对象,去初始化另一个对象的时候(注意是在定义对象初始化,不是赋值)
Student stu1;
Student stu2=stu1;//显示调用拷贝构造
Student stu3(stu2);//隐式调用拷贝构造
Student *pStu=new Student(stu3);
//2 在函数传参时,函数的形参是类对象
void fun(Student stu){}
fun(stu1);//在函数调用传参时调用拷贝构造
//3 如果一个函数的返回值类型是对象,在函数调用结束,返回对象的时候调用拷贝构造
Student fun1(Student stu)
{
return stu;
}
//这里在函数调用的时候会调用两次拷贝构造,函数传参一次,函数返回时一次
//函数返回时再次调用拷贝构造的原因:stu形参是属于栈区的,不能return出来,出了函数就直接被释放了,所以想要返回出来,就要再拷贝一次。
6、深拷贝与浅拷贝
1、浅拷贝
浅拷贝构造我们不写,系统也会提供一个默认的拷贝构造,而这个拷贝构造的操作,我们可以理解为,是用 ‘ = ’ 号一个一个的赋值的,我们将之称为,浅拷贝。在用指针的时候我们就知道两个同等类型的指针之间用 ‘ = ’ 号赋值,是两个指针的地址指向同一个内存,那么就可能会存在一个问 题,就是两个对象的指针都指向同一个内存,那么如果其中一个对象把该内存释放了,就会导致另外一个对象的指针变成野指针。
2、深拷贝
也就是在有上述问题的时候才需要深拷贝,而深拷贝做的事情也就是自己定义拷贝构造,给新的对象的指针申请内存,来存内容,而不是两个对象的指针指向同一个内存
//示例:
class Student
{
char *name;
public:
Student(char *name)
{
this->name=new char[strlen(name)+1];//加1是为了保存'\0'
strcpy(this->name,name);
}
Student(const Student& stu)
{
//这个自定义拷贝构造函数做的事,其实就是给新对象的指针申请 内存来存数据,如果有其他成员,那么也要记得赋值
this->name=new char[strlen(stu.name)+1];//加1是为了存'\0'
strcpy(this->name,s
tu.name);
}
}
什么时候要自己写拷贝构造?
类中有动态申请内存的时候,必须要写。