长春网站排名,网站开发学校 优帮云,如何免费做网站 详细点说,wordpress开发者模式一、多态的概述 多态按字面的意思就是多种形态。当类之间存在层次结构#xff0c;并且类之间是通过继承关联#xff08;父类与子类#xff09;时#xff0c;就会用到多态。 C 多态意味着调用成员函数时#xff0c;会根据调用函数的对象的类型来执行不同的函数。 静态多态并且类之间是通过继承关联父类与子类时就会用到多态。 C 多态意味着调用成员函数时会根据调用函数的对象的类型来执行不同的函数。 静态多态编译时多态早绑定函数重载、运算符重载 动态多态运行时多态晚绑定虚函数 二、虚函数
1、知识点引入 需求设计一个算法可以操作父类派生的所有子类 算法通用父类指针引用保存 子类空间地址
父类指针 保存 子类空间地址带来的问题 原因: 解决通过虚函数
2、虚函数的定义 定义及用法父类成员函数前加virtual修饰该函数即为虚函数 子类重写父类虚函数函数名、返回值类型、参数类型个数顺序完全一致。 动态多态条件有继承、子类重写(覆盖)父类的虚函数父类指针 指向子类空间。
3、虚函数原理 如果一个类中的成员函数 被virtual修饰那么这个函数就是虚函数。类就会产生一个虚函 数指针vfptr指向了一张虚函数表vftable。 如果这个类 没有涉及到继承 这时虚函数表中 纪录及时当前类的虚函数入口地址。
Animal的类的结构 一旦子类重写父类虚函数就会将子类的虚函数肉蔻地址覆盖虚函数表中原来的入口地址。
Dog的类存结构 三、纯虚函数和抽象类 在设计时常常希望基类仅仅作为其派生类的一个接口。并且不希望用户实际的创建一个基类的对象。所以创建一个纯虚函数允许接口中放置成员原函数而不一定要提供一段可能对这个函数毫无意义的代码。 一个纯虚函数(pure virtual function),使得基类称为抽象类(abstract class)抽象类 必须被继承 同时 子类 必须重写 父类的所有纯虚函数否则 子类也是抽象类。纯虚函数使用关键字virtual并在其后面加上0。抽象类 不能实例化 对象如果试图去实例化一个抽象类编译器则会阻止这种操作。
虚函数不实现函数体 class Animal
{
public://纯虚函数virtual void speak(void)0;
};抽象类主要的目的 是设计 类的接口
#include iostream
using namespace std;
//抽象制作饮品
class AbstractDrinking{
public://烧水virtual void Boil() 0;//冲泡virtual void Brew() 0;//倒入杯中virtual void PourInCup() 0;//加入辅料virtual void PutSomething() 0;//规定流程void MakeDrink(){this‐Boil();Brew();PourInCup();PutSomething();}
};//制作咖啡
class Coffee : public AbstractDrinking{
public://烧水virtual void Boil(){cout 煮农夫山泉! endl;}//冲泡virtual void Brew(){cout 冲泡咖啡! endl;}//倒入杯中virtual void PourInCup(){cout 将咖啡倒入杯中! endl;}//加入辅料virtual void PutSomething(){cout 加入牛奶! endl;}
};//制作茶水
class Tea : public AbstractDrinking{
public://烧水virtual void Boil(){cout 煮自来水! endl;
}//冲泡virtual void Brew(){cout 冲泡茶叶! endl;}//倒入杯中virtual void PourInCup(){cout 将茶水倒入杯中! endl;}//加入辅料virtual void PutSomething(){cout 加入食盐! endl;}
};//业务函数
void DoBussiness(AbstractDrinking* drink){drink‐MakeDrink();delete drink;
}int main(int argc, char *argv[])
{DoBussiness(new Coffee);//new Coffee 是在堆上分配内存创建一个 Coffee 对象然后将该对象的指针传递给 DoBussiness 函数进行处理。cout ‐‐‐‐‐‐‐‐‐‐‐‐‐‐ endl;DoBussiness(new Tea);return 0
}
虚函数 和纯虚函数的 区别 虚函数virtual修饰 有函数体 不会导致父类为抽象类。 纯虚函数virtual修饰0没有函数体 导致父类为抽象类。子类必须重写父类的所有 纯虚函数。 四、虚析构函数
构造的顺序父类---成员----子类
析构的顺序子类---成员----父类 虚析构通过父类指针 释放整个子类空间。 原理 五、纯虚析构 纯虚析构的本质是析构函数负责释放各类的空间。而且析构函数不能被继承。 故必须为纯虚析构函数提供一个函数体纯虚析构函数 必须在类外实现。
#pragma warning(disable:4996)
#includeiostream
#includestring.h
using namespace std;
class Animal
{
public://纯虚函数virtual void speak(void)0;//纯虚析构//纯虚析构函数 必须在类外实现virtual ~Animal()0;
};
class Dog:public Animal
{
public://子类重写父类的虚函数本质仍是虚函数此时关键字virtual可省void speak(void){cout 狗在汪汪 endl;}~Dog(){coutDog析构函数endl;}
};
void test()
{Animal* p new Dog;p-speak();delete p;}
int main(int argc, char* argv[])
{test();return 0;
}
//纯虚析构函数 必须在类外实现
Animal::~Animal()
{coutAnimal析构函数endl;
}
虚析构 和纯虚析构的区别
虚析构virtual修饰有函数体不会导致父类为抽象类。
纯虚析构virtual修饰0函数体必须类外实现导致父类为抽象类。
六、多态的常见问题 1、多态的分类 2、谈谈你对动态捆绑机制的理解虚函数实现原理 3、重载、重定义、重写的区别 4、虚函数和纯虚函数的区别 5、虚析构和纯虚析构的区别 6、虚函数的作用 7、虚析构的作用 八、重载、重定义、重写的区别 重载同一作用域同名函数参数的顺序、个数、类型不同 都可以重载。函数的返回值 类型不能作为重载条件例函数重载、运算符重载 重定义有继承子类 重定义 父类的同名函数非虚函数 参数顺序、个数、类型可以 不同。子类的同名函数会屏蔽父类的所有同名函数可以通过作用域解决 重写覆盖有继承子类重写 父类的虚函数。返回值类型、函数名、参数顺序、个 数、类型都必须一致。