引言
C++学习笔记(一)-CSDN博客、C++学习笔记(二)-CSDN博客、C++学习笔记(三)-CSDN博客、C++学习笔记(四)-CSDN博客、C++学习笔记(五)-CSDN博客。博主之前的几篇博客基于C语言和C++的相关知识进行了整理,然后在C++的学习笔记(五)中详细的介绍类的相关知识,本篇学习笔记将书接上文,继续整理C++的学习笔记。
一、构造函数
1.1 构造函数的语法形式
class 类名
{
public:
类名(构造函数的形参列表)
{
//构造的函数中的逻辑:就是对类对象中属性进行初始化
}
}
1.2 构造函数的意义
构造函数的意义是用来对类中的对象的属性进行初始化操作。举例说明:
//例如定义一个学生的类
class Stu
{
private:
int name;
int score;
public;
//如果类中没有提供任何的构造,编译器会为这个类型提供一个默认构造,如下所示
Stu()
{
}
Stu()
{
//提供初始化类中的属性
memset(this,0,sizeof(Stu));
}
//上面两个区别是一个是默认构造方法,另一个是还能进行初始化的方法
//当然在C++11中提供了默认构造的写法如下显示:
Stu() = default;
//构造函数相比与普通函数,少了类型和返回值,其他的和普通的函数没有什么区别
//所以构造函数也有着重载的概念
//除了上面的默认构造方式,还有着自己定义的构造方式,如:
Stu(string name, int score)
{
this -> name = name;
this -> score = score;
}
};
//在主函数中
Stu stu(“xiaobai”,100);//此时函数构造调用的是有参构造
Stu stu();//此时则调用的是无参构造
1.3 构造调用形式
构造调用形式分为显示调用和隐式调用
//举个最简单的类
class A
{
public:
A()
{
}
A(int a)
{
this ->a = a;
}
}
//主函数中
A a;
A a(1); //这两种都是显示调用
A a = 10; //这种是隐式调用
//一般情况下,为了防止出现隐式调用,使用explicit修饰构造函数,即如下形式
explicit A(int a)
{
this -> a =a;
}
注意:当类中有程序员提供的任何形式的构造,编译器将不再提供默认的构造
二、类的析构
2.1 析构的作用:
当定义类的时候如果类中有着指针属性,则应该定义析构函数,使得类对象的属性指针指向堆上资源被清理。
2.2 析构函数的语法形式:
class 类名
{
public:
~类名()
{
//释放类中指针属性指向堆上资源的逻辑;
}
}
举个例子:
class Stu
{
private:
string name;
int score;
int *p;
public:
Stu()
{
memset(this,0,sizeof(stu));
}
Stu(string name, int age)
{
this ->name = name;
this->score =score;
p = new int[100]{0};
}
~Stu() //注意析构函数的参数永远是空参
{
//清理类中属性指向的堆上资源
if(p != nullptr)
{
delete[] p;
p = nullptr;
}
}
};
注意:delete也是释放空间,但是如果类中有指针属性指向堆区资源时,使用delete释放空间,并不会将指针属性指向的堆区资源释放掉,会造成资源泄露的问题。
所以C++提供了析构函数,用来解决这个事情,并且析构函数在类对象被销毁前由编译器自动调用。