IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++虚函数和多态 -> 正文阅读

[C++知识库]C++虚函数和多态

目录

虚函数和虚函数表

虚函数和多态

纯虚函数和ADT

纯虚析构函数

?final和override

C++类型转换


虚函数和虚函数表

  1. 虚函数:用virtual修饰的成员函数
  2. 虚函数对于类的影响:增加一个指针,32位4个字节,64位8个字节
  3. 虚函数表:一个指针储存所有虚函数的首地址

虚函数和多态

多态:同一种行为(调用)产生的不同结果

多态必要性原则:

  • 父类必须存在虚函数
  • 子类必须采用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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-06 15:04:14  更:2021-12-06 15:05:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:23:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码