2024年7月15日
学习编程就得循环渐进,踏实根本,勿在浮沙筑高台
循环渐进Forward-CSDN博客
Hello,这里是kiki,本日继续更新C++部分,我们继续来扩充我们的知识面,我盼望能积极把抽象繁多的知识讲的生动又普通易懂,本日要讲的是C++三大特性的多态~
目次
循环渐进Forward-CSDN博客
多态的概念
多态的界说及实现
多态的构成条件
虚函数
虚函数的重写
虚函数重写的两个破例:
C++11 override 和 final
重载、覆盖(重写)、潜伏(重界说)的对比
抽象类
接口继续和实现继续
多态的原理
虚函数表
多态的原理
动态绑定与静态绑定
单继续和多继续关系中的虚函数表
多态的概念
多态的概念:普通来说,就是多种形态,具体点就是去完成某个举动,当差异的对象去完成时会 产生出差异的状态 。 举个栗子:比如买票这个举动 ,当 平常人 买票时,是全价买票; 门生 买票时,是半价买票; 武士买票时是优先买票。 再举个栗子: 迩来为了 争取在线付出市场 ,付出宝年底经常会做诱人的 扫红包 - 付出 - 给嘉奖金 的 活动。那么各人想想为什么有人扫的红包又大又奇怪8 块、 10 块 ... ,而有人扫的红包都是 1 毛, 5 毛.... 。实在这背后也是一个多态举动。付出宝起首会分析你的账户数据,比如你是新用户、比如你没有经常付出宝付出等等,那么你必要被鼓励利用付出宝,那么就你扫码金额 =random()%99;比如你经常利用付出宝付出大概付出宝账户中常年没钱,那么就不必要太鼓励你去利用付出宝,那么就你扫码金额 = random()%1 ;总结一下: 同样是扫码动作,差异的用户扫 得到的不一样的红包,这也是一种多态举动。 ps :付出宝红包标题纯属瞎编,各人仅供娱乐。
多态的界说及实现
多态的构成条件
多态是在差异继续关系的类对象,去调用同一函数,产生了差异的举动。比如Student 继续了 Person 。 Person 对象买票全价, Student对象买票半价。 那么在继续中要构成多态尚有两个条件:
1. 必须通过基类的指针大概引用 调用虚函数 2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数举行 重写
虚函数
虚函数:即被 virtual 修饰的类成员函数称为虚函数。 - class Person {
- public:
- virtual void BuyTicket() { cout << "买票-全价" << endl; }
- };
复制代码 虚函数的重写
虚函数的重写(覆盖):派生类中有一个跟基类完全类似的虚函数(即派生类虚函数与基类虚函数的返回值范例、函数名字、参数列表完全类似),称子类的虚函数重写了基类的虚函数。
- class Person {
- public:
- virtual void BuyTicket() { cout << "买票-全价" << endl; }
- };class Student : public Person {public: virtual void BuyTicket() { cout << "买票-半价" << endl; }};
复制代码 虚函数重写的两个破例:
1. 协变 ( 基类与派生类虚函数返回值范例差异 ) 派生类重写基类虚函数时,与基类虚函数返回值范例差异。即基类虚函数返回基类对象的指 针大概引用,派生类虚函数返回派生类对象的指针大概引用时,称为协变。(相识) - 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; }
- };
复制代码 2. 析构函数的重写(基类与派生类析构函数的名字差异)
如果基类的析构函数为虚函数,此时派生类析构函数只要界说,无论是否加 virtual 关键字, 都与基类的析构函数构成重写,固然基类与派生类析构函数名字差异。固然函数名不类似, 看起来违反了重写的规则,实在否则,这里可以明白为编译器对析构函数的名称做了特殊处 理,编译后析构函数的名称同一处置处罚成 destructor 。 - class Person {
- public:
- virtual ~Person() { cout << "~Person()" << endl; }
- };
- class Student : public Person {
- public:
- virtual ~Student() { cout << "~Student()" << endl; }
- };
- // 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
- 数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
- int main()
- {
- Person* p1 = new Person;
- Person* p2 = new Student;
- delete p1;
- delete p2;
- return 0;
- }
复制代码 C++11 override 和 final
C++11 提供了 override 和 final 两个关键字,可以帮 助用户检测是否重写。 1. final:修饰虚函数,表现该虚函数不能再被重写
- class Car
- {
- public:
- virtual void Drive() final {}
- };
- class Benz :public Car
- {
- public:
- virtual void Drive() {cout << "Benz-舒适" << endl;}
- };
复制代码 2. override: 查抄派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。 - class Car{
- public:
- virtual void Drive(){}
- };
- class Benz :public Car {
- public:
- virtual void Drive() override {cout << "Benz-舒适" << endl;}
- };
复制代码 重载、覆盖(重写)、潜伏(重界说)的对比
抽象类
在虚函数的反面写上 =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();
- }
复制代码 接口继续和实现继续
平常函数的继续是一种实现继续,派生类继续了基类函数,可以利用函数,继续的是函数的实现。虚函数的继续是一种接口继续,派生类继续的是基类虚函数的接口,目标是为了重写,告竣多态,继续的是接口。以是如果不实现多态,不要把函数界说成虚函数。 多态的原理
虚函数表
一个含有虚函数的类中都至少都有一个虚函数表指针,由于虚函数的所在要被放到虚函数表中,虚函数表也简称虚表 多态的原理
1. 观察下图的赤色箭头我们看到, p 是指向 mike 对象时, p->BuyTicket 在 mike 的虚表中找到虚函数是Person::BuyTicket 。 2. 观察下图的蓝色箭头我们看到, p 是指向 johnson 对象时, p->BuyTicket 在 johson 的虚表中 找到虚函数是 Student::BuyTicket 。 3. 如许就实现出了差异对象去完成同一举动时,显现出差异的形态。 4. 反过来思索我们要到达多态,有两个条件,一个是虚函数覆盖,一个是对象的指针或引用调用虚函数。反思一下为什么? 5. 再通过下面的汇编代码分析, 看出满意多态以后的函数调用,不是在编译时确定的,是运行 起来以后到对象的中取找的。不满意多态的函数调用时编译时确认好的 。
动态绑定与静态绑定
1. 静态绑定又称为前期绑定 ( 早绑定 ) , 在步调编译期间确定了步调的举动 , 也称为静态多态 , 比如:函数重载 2. 动态绑定又称后期绑定 ( 晚绑定 ) ,是在步调运行期间,根据具体拿到的范例确定步调的具体举动,调用具体的函数,也称为动态多态 。 单继续和多继续关系中的虚函数表
必要注意的是在单继续和多继续关系中,下面我们去关注的是派生类对象的虚表模子,由于基类的虚表模子前面我们已经看过了,没什么必要特殊研究的
学习编程就得循环渐进,踏实根本,勿在浮沙筑高台
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |