c++的多态《一》 主要包括:《多态的概念》《多态的定义及实现》《重载,重写,重定义的对比》《不规范的重写及析构函数的重写问题》《抽象类—纯虚函数》《关键字final》

本文深入探讨C++中的多态概念,包括多态的定义与实现、虚函数的重写规则、抽象类与纯虚函数的作用,以及如何通过关键字final限制虚函数的重写。同时,文章提供了丰富的代码示例,帮助读者理解多态性和抽象类的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态《二》的链接:https://blog.youkuaiyun.com/dpfxaca6/article/details/89521976
多态《三》的链接:https://blog.youkuaiyun.com/dpfxaca6/article/details/89576789
《一》 多态的概念

概念:通俗来讲,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生不同的状态。

《 二 》多态的定义及实现

(1)多态定义的构成条件

多态是不同继承关系的类和对象,去调用同一个函数,产生不同的的行为,比如:Student继承Preson类,Preson对象买全票,Student买半票。

那么在继承中构建多态的有两种情况

一种是:调用的函数必须是是指针或者引用。
一种是:被调用的函数,必须是虚函数,并且完成了虚函数的重写。

#include<iostream>
using  namespace std;

class Preson
{
public:
	virtual void BuyTicket()
	{
		cout << "买全票" << endl;
	}
};
class Student :public Preson
{
	virtual void BuyTicket()
	{
		cout << "买半票" << endl;
	}
};

void Func(Preson& people)
{
	people.BuyTicket();
}
int main()
{
	Preson p;
	//Func(p);
	p.BuyTicket();

	Student s;
	Func(s);
	//使用下面这个会出现错误,因为我们上面使用virtual关键字了,
	//s.BuyTicket(); 

	return 0;
}

为什么使用virtual关键,这样就使他变成了 虚函数了 ,就是直接指向它了的基类,解决了二义性的问题,前面我们也说过了。

虚函数是什么?

答:就是我们上面在函数前面写的virtual关键字之后,此函数就是虚函数。

什么是虚函数的重写?

答;派生类中有一个跟基类的完全相同虚函数,我们就称子类的虚函数重写了基类的虚函数,完
全相同是指:函数名、参数、返回值都相同。另外虚函数的重写也叫作虚函数的覆盖。

class Person {
public:
         virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
           virtual void BuyTicket() { cout << "买票-半价" << endl; }
};
void Func(Person& p)
{
                p.BuyTicket();
}

(2)虚函数的重写例外:协变

class A{};
class B : public A {};
class Person {
public:
	virtual A* f()
	{
		return new A;
	}
};
class Student : public Person {
public:
	virtual B* f() 
	{ 
		return new B;

	}
};

void func(Person& ps)
{
	ps.f();
}
int main()
{
	Person p;
	func(p);

	Student s;
	func(s);
}

我们把上面的这段代码,放在编译器中,我们可以看到,是没有一点的错误的,所以说这样也是可以的,但是这不是我们正规的写法,所以说,我们一般是使用上面的写法的。

(3)不规范的重写行为

在派生类中重写的成员函数可以不加virtual关键字,也是构成重写的,因为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性,我们只是重写了它。但是这是非常不规范的,所以我们一般是不使用这样的写法的

class Person {
    public:
             virtual void BuyTicket() { cout << "买票-全价" << endl; }
    };
    class Student : public Person {
    public:
               void BuyTicket() { cout << "买票-半价" << endl; }
    };

这样写,也是可以的,但是不规范。

(4)析构函数的重写问题

基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor,这也说明的基类的析构函数最好写成虚函数。

class Person {
public:
	virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:
	virtual ~Student() { cout << "~Student()" << endl; }
};

int main()
{
	Person* p1 = new Person;
	Person* p2 = new Student;
	delete p1;
	delete p2;
	return 0;
}

下面我们看一下执行的代码:
在这里插入图片描述
【 绿色表示,他先找到基类,然后再找到派生类,然后析构是,先派生类在基类顺序 】

(5)重载,覆盖(重写),隐藏(重定义)的对比
在这里插入图片描述
《三》抽象类

抽象类的定义:在虚函数的后面写上 =0,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

class Car
{
public:
    virtual void Drive() = 0;
};
class Benz :public Car
{
public:
	    virtual void Drive()
	    {
	           cout << "Benz-舒适" << endl;
	    }
};
class BMW :public Car
{
 public:
    virtual void Drive()
    {
           cout << "BMW-操控" << endl;
    }
};
void Test()
{
    Car* pBenz = new Benz;
    pBenz->Drive();
    Car* pBMW = new BMW;
    pBMW->Drive();
}

   int main()
    {
       Test();
       return 0;
    }

这里的这段代码 就说明了 上面的这段描述,如果看上面的文字不太理解,就配合下面的文字一起看。

下面还有一种:

class Car{
public:
	virtual void Drive()
	{}
};
// 2.override 修饰派生类虚函数强制完成重写
class Benz :public Car {
public:
	virtual void Drive() override
	{
		cout << "Benz-舒适" << endl;
	}
};
void Test()
{
	Car* pBenz = new Benz;
	pBenz->Drive();
	//Car* pBMW = new BMW;
	//pBMW->Drive();
}

int main()
{
	Test();
	return 0;
}

实际中我们建议多使用纯虚函数+ overrid的方式来强制重写虚函数,因为虚函数的意义就是实现多态,如果没有重写,虚函数就没有意义。

《四》关键字final (c++11)
final修饰基类的虚函数不能被派生类重写

class Car
{
public:
virtual void Drive() final {}
};
class Benz :public Car
{
public:
virtual void Drive() { cout << “Benz-舒适” << endl; }
};

这里我们看一下程序的图片,就比较好理解

在这里插入图片描述
这里的内容有一点多,我在另外写一篇博客,会把链接放在下面的 ,提供方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值