C++笔记--类和对象--多态(其二)

本文详细介绍了C++中纯虚函数和抽象类的概念,以及它们在多态中的作用。重点讲解了如何使用纯虚函数实现抽象类,以及虚析构和纯虚析构的区别和应用场景,帮助读者理解这些高级特性以避免内存泄漏。
摘要由CSDN通过智能技术生成

目录

4. 纯虚函数和抽象类

       4.1. 纯虚函数语法

       4.2. 抽象类的特点

       4.3. 代码演示

5. 虚析构与纯虚析构

       5.1. 虚析构和纯虚析构的共性与区别

       5.2. 语法

       5.3. 代码演示

其一:C++笔记--类和对象--多态(其一)



4. 纯虚函数和抽象类

        在多态中,通常父类中的虚函数都用于子类的重写,自身没什么意义,所以,可以改为纯虚

函数

       4.1. 纯虚函数语法

        virtual 返回类型 函数名(参数列表)= 0;(不需要加{}哦)

        当类中有至少一个纯虚函数时,该类又称抽象类

       4.2. 抽象类的特点

        • 无法实例化对象。

        • 其子类必须对其中的纯虚函数进行重写,否则子类也属于抽象类。

       4.3. 代码演示

        接下来,看看示例代码

class Base
{
public:
    //纯虚函数
	virtual void func() = 0;
};

class Son:public Base
{
public:
	void func()
	{
		cout << "耶耶耶耶耶" << endl;
	}
};

void text01()
{
    //Base b;//此代码会报错

	Base* a = new Son();
	a->func();
}

        以上代码应当不难理解,就是关于纯虚函数和抽象类在代码里的体现。(其中Base为抽象类)

5. 虚析构与纯虚析构

        当子类中有堆区数据时,父类指针在释放时(Base* a = new Son();delete a;)无法调用到子类的析构函数,此时,就需要将父类的析构函数改成虚析构纯虚析构

       5.1. 虚析构和纯虚析构的共性与区别

        共性:

        • 都可以解决父类指针释放子类对象的难题

        • 都需要具体的函数

        区别:

        • 若有纯虚析构,则该类属于抽象类,无法实例化对象 

       5.2. 语法

        虚析构——virtual ~类名(){}

        纯虚析构—virtual ~类名(){} = 0;(要写;的)

       5.3. 代码演示

        接下来,上代码,先看看无虚析构时会怎样

//父类
class Animal
{
public:
    //构造函数
	Animal()
	{
        //指示Animal构造函数的调用
		cout << "Animal构造函数调用" << endl;
	}
    //纯虚函数
	virtual void speak() = 0;
    //析构函数
	~Animal()
	{
        //指示Animal析构函数的调用
		cout << "Animal析构函数调用" << endl;
	}
};

class Cat :public Animal
{
public:
    //有参构造
	Cat(string name)
	{
        //指示Cat构造函数的调用
		cout << "Cat构造函数调用" << endl;
        //在堆区开辟
		m_Name = new string(name);
	}
    //重写
	void speak()
	{
		cout << *m_Name << "喵喵叫" << endl;
	}
    //析构函数
	~Cat()
	{
        //指示Cat析构函数的调用
		cout << "Cat析构函数调用" << endl;
        //对堆区数据的释放
		if (m_Name != NULL)
		{
			delete m_Name;
			m_Name = NULL;
		}
	}
    //接收堆区数据的属性
	string* m_Name;
};
void text01()
{
	Animal* a = new Cat("小花");
	a->speak();
	delete a;
}

        以上代码运行之后,应该是这样的

        可以清晰地看到,子类Cat的析构函数没有被调用,如此,会出现内存的泄露。

        只需在Animal的析构函数前面加virtual即可解决这个问题,在此不再列举。

        将Animal的析构函数换成如下代码,即为纯虚析构

        virtual ~Animal() = 0;

        但是,在该代码中,如果如此写,就会报错,因为,上面的运行图中,Animal的析构函数是有调用的,而且,倘若,父类中也有属性开辟在堆区,那析构函数是不得不用的。

        因此,代码要变成这样

class Animal
{
public:
	Animal()
	{
		cout << "Animal构造函数调用" << endl;
	}
	virtual void speak() = 0;
	virtual ~Animal() = 0;
	/*{
		cout << "Animal析构函数调用" << endl;
	}*/
};
//类外
Animal:: ~Animal()
{
	cout << "Animal纯析构函数调用" << endl;
}

        另外,此时,Animal类为抽象类。

        最后,问大家一下,虚析构和纯虚析构是用来干什么的来着?

其一:C++笔记--类和对象--多态(其一)

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值