1. 类的析构函数
析构函数的作用,用于释放该类所占用的资源(或者说释放对象)在类的对象使用完时(当类的对象超出了作用域),会自动调用析构函数;如果是在堆区实例化的对象,那么当手动释放对象时,会自动调用析构函数
析构函数的原型:~类名()//析构函数{}例如:~People() {//释放指针占用的空间delete p;}
2.友元
C++提供友元目的是给类的外部提供一个访问类的私有成员的接口,即可以通过友元访问类的私有成员
友:friend
2.1友元函数
将一个类的成员函数可不可以声明为另外一个类的友元?一个类的成员函数声明为另外一个类的友元,可不可以访问另外一个类的私有成员?
编译器提示错误:不可访问
关键字:friend格式:friend函数返回值 函数名(参数列表); //声明一个友元函数例如:friendvoidfunction();//function函数是一个友元函数
注意:
友元函数属不属于类的成员?友元函数不是类的成员函数
friend_main.cpp
//友元函数class People {public://将function函数声明为People的友元//注意:友元函数不是类的成员函数friend void function(People& people);private:int a=10;//普通类型变量};//定义一个函数去访问a,因为a是类中私有,一般是访问不到的//所以我们需要将此函数在类中声明为友元函数void function(People& people) {cout << "友元函数访问到a = " << people.a << endl;}int main(){People people1;function(people1);return 0;}
2.1.2练习
使用类和对象以及友元实现算数表达式的求值
例如:2+5+6-4+4-40的和
main5.cpp
#include "iostream"using namespace std;//使用类和对象以及友元实现算数表达式的求值//例如://2 + 5 + 6 - 4 + 4 - 40的和class Jia{public://构造函数,给属性赋值Jia(int m, int n){a = m;b = n;}//声明友元函数friend void jiaFa(int a1, Jia& jia);void print(){cout << "temp=" << temp << endl;}//声明友元函数friend void update_a(Jia& jia, int a1);int temp;//临时存储结果,方便减法加法之间传递private:int a;int b;};//加法void jiaFa(int a1, Jia& jia){jia.b = a1;jia.a = jia.a + jia.b;//我们使用a来临时存储结果jia.temp = jia.a; //因为a是私有的在做减法时,需要将之前的结果传递给减法所以我们取出a的值给tmp,时tmp为公有方可传递给减法}//更新a的值void update_a(Jia& jia, int a1){jia.a = a1;}class Jian{public://声明友元函数friend void jianFa(int a1, int b1, Jian& jian);int temp;//临时存储结果,方便减法加法之间传递};//减法voidjianFa(int a1, int b1, Jian& jian){jian.temp = a1 - b1;}int main(){Jia jia(2, 5);jiaFa(5, jia);jiaFa(6, jia);jia.print();Jian jian;jianFa(jia.temp, 4, jian);//jian.temp=9update_a(jia, jian.temp);//更新a的值,使a中的临时结果,保持最新jiaFa(4, jia);jianFa(jia.temp, 40, jian);cout << "最终的结果:" << jian.temp << endl;return 0;}
2.2友元类
关键字:friend格式:friendclass 类名; //将类声明为友元例如:friend class People;
friend_main.cpp
//友元类class People {public://将function函数声明为People的友元//注意:友元函数不是类的成员函数friend void function(People& people);//将Animal声明为友元类friend class Animal;private:int a = 10;//普通类型变量};class Animal {public:void print(const People& people) {cout << "animal类中访问到a = " << people.a << endl;}};//定义一个函数去访问a,因为a是类中私有,一般是访问不到的//所以我们需要将此函数在类中声明为友元函数void function(People& people) {cout << "友元函数访问到a = " << people.a << endl;}int main(){People people1;function(people1);//友元函数访问Animal animal;animal.print(people1);//友元类访问return 0;}
3.经典问题
3.1构造函数和普通函数的区别:
(1)目的:
构造函数用于在对象被创建时初始化对象的成员变量。它确保对象在被使用之前处于一个合适的状态。
普通函数用于执行一般的任务和操作,它们不关心对象的创建和销毁。
(2)调用时机:
构造函数在对象创建时自动调用,无需显式调用。它们确保对象在被使用前处于有效状态。
普通函数需要在代码中显式调用。
(3)返回类型:
构造函数没有返回类型,包括没有void。它们只是在对象创建时执行,初始化对象的状态。
普通函数有返回类型,可以返回一个值。
(4)命名:
构造函数的名称与类的名称相同。
普通函数有自定义的名称。
(5)用法:
构造函数主要用于初始化对象的状态,通常包括分配资源、设置默认值等。
普通函数可以执行各种任务,而不涉及对象的创建和销毁。
3.2析构函数和普通函数的区别:
(1)目的:
析构函数用于在对象被销毁时释放资源、清理对象状态。
普通函数执行一般任务,通常不涉及对象的销毁。
(2)调用时机:
析构函数在对象生命周期结束时自动调用,无需显式调用。
普通函数需要在代码中显式调用。
(3)返回类型:
析构函数没有返回类型,包括没有void。它们只是在对象销毁时执行清理操作。
普通函数有返回类型,可以返回一个值。
(4)命名:
析构函数的名称与类的名称相同,但前面有一个波浪线~。
普通函数有自定义的名称。
(5)用法:
析构函数主要用于释放对象在其生命周期中分配的资源,如动态分配的内存、打开的文件等。
普通函数可以执行各种任务,而不涉及对象的销毁。
3.3malloc/new和free/delete的区别
malloc:
是一个函数。
用于分配一块指定大小的内存块。
返回void*类型的指针,因此在使用时通常需要显式地进行类型转换。(需要手动进行类 型转换)
不会调用对象的构造函数或析构函数,因为它主要用于分配原始内存。
new:
只是一个操作符。
用于在堆上创建一个对象,并调用对象的构造函数。
返回具体类型的指针,不需要显式类型转换。
用于在堆上创建一个对象,并调用对象的构造函数。
free:
是一个函数。
用于释放先前由malloc分配的内存。
delete:
是一个操作符。
用于释放先前由new创建的对象,并调用对象的析构函数。
会调用对象的析构函数,用于对象的清理和资源释放。