C++虚函数和多态
2021/12/6 1:20:09
本文主要是介绍C++虚函数和多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
虚函数和虚函数表
- 虚函数:用virtual修饰的成员函数
- 虚函数对于类的影响:增加一个指针,32位4个字节,64位8个字节
- 虚函数表:一个指针储存所有虚函数的首地址
虚函数和多态
多态:同一种行为(调用)产生的不同结果
多态必要性原则:
- 父类必须存在虚函数
- 子类必须采用public继承
- 必须存在指针的使用
#include<iostream> using namespace std; class Ins{ public: void func(){ cout << "你好!" << endl; } virtual void func1(){ cout << "他好!" << endl; } protected: }; class Owe:public Ins { public: void func(){ cout << "你不好!" << endl; } void func1(){ cout << "他不好!" << endl; } protected: }; int main(){ //有virtual看对象类型,没virtual看指针类型 Ins* i = new Owe; i->func();//不是虚函数 i->func1();//虚函数 i = new Ins; i->func1(); while (1); return 0; }
输出如图结果:
多态的作用:可以减少在源代码基础上修改,而是改为增加代码来达到所要的效果
纯虚函数和ADT
纯虚函数:是没有函数体的虚函数
作用:做ADT(abstract data type抽象数据类型)过程
在类中的写法:
virtual void function()=0;
抽象类:具有至少一个纯虚函数的类叫抽象类
- 抽象类不能构造对象
- 抽象类可以构造对象指针
#include<iostream> using namespace std; class stack{ public: virtual void push(int data) = 0; virtual void pop() = 0; virtual int top()const = 0; virtual bool empty()const = 0; virtual int size()const = 0; protected: }; //子类要想创建对象必须重写父类的纯虚函数 //ADT过程:具有强迫性,所有子类重写函数必须与父类一样 class arrayStack :public stack{ public: void push(int data){}; void pop(){}; int top()const{ return 1; }; bool empty()const { return true; }; int size()const{ return 1; }; protected: }; class listStack :public stack{ public: void push(int data){}; void pop(){}; int top()const{ return 1; }; bool empty()const { return true; }; int size()const{ return 1; }; protected: }; void testStack(stack* p){ p->push(0); while (!p->empty()){ cout << p->top() << endl; p->pop(); } } int main(){ testStack(new arrayStack); testStack(new listStack); while (1); return 0; }
纯虚析构函数
在用子类对象初始化父类指针的时候,父类需要写虚析构函数做内存的释放
#include<iostream> using namespace std; class parent{ public: //virtual ~parent(){ // cout << "父类" << endl; //} protected: }; class kid:public parent{ public: ~kid(){ cout << "子类" << endl; } protected: }; int main(){ parent* ptr = new kid; delete ptr; ptr = nullptr; while (1); return 0; }
final和override
final和override:final :禁止重写(只在继承中使用),只能用于虚函数和,子类不能存在同名函数,override强制重写,标识作用,检查父类中是否存在当前虚函数
class parent{ public: virtual void func() final{} virtual void func1(){} protected: }; class child:public parent{ public: //不能使用与父辈同名的函数void func(){}; void func1()override{}//标识作用,如果父类不存在同名虚函数就会报错 protected: };
C++类型转换
格式: 关键字 _cast<要转换的类型>(要转换的目标)
- const_cast:作用:1.去掉const属性(提供一个接口操作const属性) 2.加上const属性
int num=1; const int&p = num; int&pp = const_cast<int&>(p);//去掉const属性 int a = 5; int*ptr = &a; const int*pr = const_cast<const int*>(ptr);//加上const属性,用的比较少,不写const_cast也可以隐式转换,即:const int*pr=ptr;
- static_cast:
1.基本数据类型转换
2.把空指针转换成相应类型指针
3.把任何类型变量转化成void类型
4.用在基类和派生类的对象之间的转换:
进行上行转换(从子到父,指针或引用转换)
进行下行转换(从父到子,指针或引用转换)
注:static_cast不能用于去掉const
- dynamic_cast:
1.上行转换(和static_cast一样)
2.下行转换(dynamic更安全)
#include<iostream> #include<string> using namespace std; class parent{ public: virtual void print(){ cout << str << endl; } protected: string str = "ILoveYou!"; }; class child:public parent{ public: void print(){ cout << str1 << endl; } protected: string str1 = "Hello!"; }; int main(){ parent* p=new parent; child* q=new child; //上行转换 parent* l = static_cast<parent*>(q); parent* u = dynamic_cast<parent*>(q); l->print(); u->print(); //下行转换 child* h = static_cast<child*>(p); child* k = dynamic_cast<child*>(p);//dynamic可以检验父类中是否存在多态 if (k!=nullptr) k->print(); h->print(); while (1); return 0; }
3.交叉转换(多继承)
#include<iostream> using namespace std; class A{ public: virtual void print(){ cout << 'A'<<endl ;} protected: }; class B{ public: virtual void print(){ cout << 'B' << endl; } protected: }; class C:public A,public B{ public: void print(){ cout << 'C' << endl; } protected: }; int main(){ //交叉转换 A* a = new C; B* b = dynamic_cast<B*>(a); b->print(); while (1); return 0; }
- reinterpret_cast:把数转换成指针,把指针转换成数
#include<iostream> using namespace std; int Max(int a, int b) { return a > b ? a : b; } int main(){ int num = reinterpret_cast<int>(Max); cout << num << endl; cout << Max << endl; auto p = reinterpret_cast<int(*)(int a, int b)>(num); cout << p(1, 2) << endl; while (1); return 0; }
这篇关于C++虚函数和多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升