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++知识库 -> 虚函数、纯虚函数、虚继承——virtual关键字的小例子 -> 正文阅读

[C++知识库]虚函数、纯虚函数、虚继承——virtual关键字的小例子

虚函数

虚函数是C++的运行时多态,可以在基类中将被重写的成员函数设置为虚函数

虚函数的作用是:当通过基类的指针或引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。

例子如下所示:

  1. 我们定义一个基类Shape,令Rectangle类继承自Shape
  2. 我们写两个函数:outputTypeoutputTypeWithoutVirtual,在子类中对其进行重写。
  3. 在测试类中,我们创建一个Rectangle对象,然后使用Shape指针获取Rectangle对象的引用,然后分别调用虚函数和非虚函数。
#include<iostream>

namespace dcp{
	class Shape{
	public:
		virtual int getArea(){
			return 0;
		}
		//虚函数 
		virtual void outputType(){
			std::cout<<"this is shape?"<<std::endl;
		}
		//非虚函数
		void outputTypeWithoutVirtual(){
			std::cout<<"this is shape!"<<std::endl;
		} 
	};
	
	class Rectangle:public Shape{
	public:
		int getArea(){
			return length*width;
		}
		//继承后重写虚函数 
		void outputType(){
			std::cout<<"this is rectangle"<<std::endl;
		}
		//继承非虚函数后重写函数 
		void outputTypeWithoutVirtual(){
			std::cout<<"this is rectangle!"<<std::endl;
		} 
		int length;
		int width;
	};
	class Test{
	public:
		static void runTestMain(){
			Rectangle rectangle;
			Shape* shape = &rectangle;
			shape->outputType();
			shape->outputTypeWithoutVirtual();
		}
	};
}

在main.cpp调用,

#include <iostream>
#include"dynamic_cast_principle.cpp"
int main(int argc, char** argv) {
	dcp::Test::runTestMain();
}

得到如下结果:带有virtual关键字的函数被重写后,最终调用的是子类函数,不带有virtual调用的是父类本身的函数。

在这里插入图片描述
所以虚函数的作用是:当通过基类的指针或引用调用该成员函数时,将根据指针指向的对象类型确定调用的函数,而非指针的类型。

纯虚函数

纯虚函数通常需要在类声明的后面加上关键字"=0"。

有纯虚函数的类是抽象类,只能被继承,不能用来声明对象

简单的修改一下上面的例子,将Shape中的getArea改成如下纯虚函数的形式:

virtual int getArea()=0;

然后编译以下的代码会报错:

Shape shape;

报错信息如下,意思是Shape是抽象函数不能实例化(如果Rectangle这时没有实现getArea函数,那么Rectangle也不能实例化,因为没有实现所有基类纯虚函数的Rectangle也被认为抽象函数)。
在这里插入图片描述

虚继承

有时候会出现一个类被继承两次的情况,如下是一种多继承关系,Unit的属性在Knight中出现了2次:
在这里插入图片描述

#include<iostream>

namespace vt{
	class Unit{
	public:
		int x,y;
	};
	
	class Enemy:public Unit{
	public:
		int hp;
	};
	
	class Soldier:public Unit{
	public:
		int atk;
	};
	
	class Knight:public Enemy,public Soldier{
	public:
		int def;
		void Attack(){
			std::cout<<x<<","<<y<<"attack!"<<std::endl;
		}
	};
	
	class Test{
	public:
		static void RunTestMain(){
			Knight knight;
			knight.x=1;
		}
	};
}

上面Attack()函数中使用了Unit的属性x、y,但是由于这个x、y可能来自于两个基类,所以无法编译成功,如下所示。这就是二义性

在这里插入图片描述
想要解决这个问题,只要进行虚继承即可,如下所示。

	class Unit{
	public:
		int x,y;
	};
	
	class Enemy:virtual public Unit{
	public:
		int hp;
	};
	
	class Soldier:virtual public Unit{
	public:
		int atk;
	};
	
	class Knight:public Enemy,public Soldier{
	public:
		int def;
		void attack(){
			std::cout<<x<<","<<y<<"attack!"<<std::endl;
		}
	};

简而言之,虚基类可以使得从多个类(它们继承自一个类)中派生出的对象只继承一个对象。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:14:05  更:2022-01-04 13:16:26 
 
开发: 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:39:16-

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