三十、纯虚函数、抽象类、多态、简单工厂模式

2023-11-16

一、纯虚函数
          虚函数是多态是实现多态的前提,如果我们需要在基类中定义共同的结构,那么接口就需要定义成虚函数。但是很多情况下基类的接口是无法实现的,比如形状类Shape,定义一个Draw方法。很明显这个方法没法实现,因为我们可以画出圆,正方形,但是不能画出"形状"。此时我们可以将这些接口定义成虚函数。
          在基类中不能给出有意义的虚函数定义,这时可以把它说明成纯虚函数,把它的定义留给派生类来做,如果派生类没有实现,那么派生类也是纯虚函数, 纯虚函数不需要实现
纯虚函数定义:

  class 类名{

       virtual 返回值类型 函数名(参数表) = 0

    };

二、简单工厂模式

          工厂方法模式(Factory method pattern)是一种实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

纯虚函数和简单工厂模式示例:

二、抽象类
          包含纯虚函数的类我们称作抽象类。
作用:抽象类为抽象和设计的目的而声明,将有关的数据和行为组织在一个继承层次结构中,保证派生类具有要求的行为。
对于暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现。
注意:
  • 抽象类只能作为基类来使用。(因为抽象类不能创建对象,只能被派生类实现)
  • 构造函数不能是虚函数,析构函数可以是虚函数。
  • 抽象类不能用于直接创建对象实例,可以声明抽象类的指针和引用
  • 可使用指向抽象类的指针支持运行时多态性
  • 派生类中必须实现基类中的纯虚函数,否则它仍将被看作一个抽象类
简单工厂模式和抽象类示例:
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Shape
{
public:
	virtual void Draw() = 0;
	virtual ~Shape() {}
};

class Circle : public Shape
{
public:
	void Draw()
	{
		cout<<"Circle::Draw() ..."<<endl;
	}
	~Circle()
	{
		cout<<"~Circle ..."<<endl;
	}
};

class Square : public Shape
{
public:
	void Draw()
	{
		cout<<"Square::Draw() ..."<<endl;
	}
	~Square()
	{
		cout<<"~Square ..."<<endl;
	}
};

class Rectangle : public Shape
{
public:
	void Draw()
	{
		cout<<"Rectangle::Draw() ..."<<endl;
	}
	~Rectangle()
	{
		cout<<"~Rectangle ..."<<endl;
	}
};

void DrawAllShapes(const vector<Shape*>& v)
{
	vector<Shape*>::const_iterator it;
	for (it=v.begin(); it!=v.end(); ++it)
	{
		(*it)->Draw();
	}
}

void DeleteAllShapes(const vector<Shape*>& v)
{
	vector<Shape*>::const_iterator it;
	for (it=v.begin(); it!=v.end(); ++it)
	{
		delete(*it);
	}
}

// 简单工厂模式
class ShapeFactory
{
public:
	static Shape* CreateShape(const string& name)
	{
		Shape* ps = 0;
		if (name == "Circle")
		{
			ps = new Circle;
		}
		else if (name == "Square")
		{
			ps = new Square;
		}
		else if (name == "Rectangle")
		{
			ps = new Rectangle;
		}

		return ps;
	}
};

int main(void)
{
	//Shape s;		//Error,不能实例化抽象类
	vector<Shape*> v;
	//Shape* ps;
	//ps = new Circle;
	//v.push_back(ps);
	//ps = new Square;
	//v.push_back(ps);
	//ps = new Rectangle;
	//v.push_back(ps);
	Shape* ps;
	ps = ShapeFactory::CreateShape("Circle");
	v.push_back(ps);
	ps = ShapeFactory::CreateShape("Square");
	v.push_back(ps);
	ps = ShapeFactory::CreateShape("Rectangle");
	v.push_back(ps);

	DrawAllShapes(v);
	DeleteAllShapes(v);


	return 0;
}

三、多态好处
1、多态性有助于更好地对程序进行抽象
  • 控制模块能专注于一般性问题的处理
  • 具体的操作交给具体的对象去做
2、多态性有助于提高程序的可扩展性
  • 可以把控制模块与被操作的对象分开
  • 可以添加已定义类的新对象,并能管理该对象
  • 可以添加新类(已有类的派生类)的新对象,并能管理该对象
四、虚析构函数
          前面我们讲过析构函数可以声明为虚函数,这样我们 delete 基类指针的时候,就会释放基类指针的指向的对象的内存。也就是说, 程序会根据基类指针指向的对象的类型确定要调用的析构函数。 如果 基类的析构函数为虚函数,那么所有派生类的析构函数都是虚函数。但是 构造函数不得是虚函数,这个在前面也已经讲过。
          最后 析构函数还可以是纯虚的,它的使用场景是:对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚析构函数声明为纯虚的,通常情况下在基类中纯虚函数不需要实现,但是纯虚析构函数要给出实现。(给出一个空的实现即可)
示例:
#include <iostream>
using namespace std;
class Base
{
public:
	virtual ~Base() = 0
	{
	}
};

class Drived : public Base
{
};

int main(void)
{
	Drived d;
	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三十、纯虚函数、抽象类、多态、简单工厂模式 的相关文章

  • qt输出到控制台

    include
  • 面向对象的编程思想和Python的类,访问和属性,继承

    面向对象的编程思想和Python的类 类的方法和属性 实例方法 这一文从面相对象的角度 介绍类的定义 类的属性和自定义方法 本文将从访问限制 属性 继承 方法重写这几个方面继续介绍面向对象的编程思想和Python类的继承 一 访问权限 Py
  • C++11多线程之条件变量

    文章目录 一 关于多线程的同步 二 初始条件变量 三 关于条件变量的例题 四 生产者消费者模型 一 关于多线程的同步 函数被调用 分配相应的栈帧 进行现场保护 void func char c char filename 20 sprint
  • C# 全局变量与局部变量

    C 在变量之间有一个基本的区分 把在类型级别声明的变量看作字段 全局变量 而把方法级别声明的变量看作局部变量 class ScopeTest static int j 20 public static void Main int j 30
  • 【C++】Vector和String详解

    前言 没错 我又更新了 即使没人看 上一篇文章介绍了有关双向链表的容器list 那问题来了 数组和字符串这种使用频率非常高的数据结构 在STL模板中会不会有让人眼前一亮的实现哪 很明显 有 vertor和string就是这两种数据结构相对应
  • 【千律】C++基础:类的构造函数和初始化

    include
  • Objective-C中的继承与多态, Category, Extension

    1 继承与多态 先要理解实例变量的作用域 再看继承 即 子类的方法和属性 从父类继承得到的方法和属性 子类新增的方法和属性 例子 Person h import
  • 【千律】C++基础:类定义和类实现的分离

    类定义就是指定义类名 是 h文件 类实现是指对类定义的具体实现 是 cpp文件 下面是Student h中的内容 pragma once include
  • 在C++中 ,什么时候用:: ?什么时候用. ?什么时候用->?

    在C 中 什么时候用 什么时候用 什么时候用 gt 在 C 中 和 gt 是三种不同的运算符 用于访问类 结构体 命名空间 指针等的成员 它们的使用场景如下 作用域解析运算符 用于访问命名空间的成员或静态成员 例如 假设有一个命名空间 My
  • 老司机带你入门Java基础概念

    因为学习所以收获 因为收获所以不寂寞 请关注 源码猎人 目录 Java简介 Java特性 Java环境概述 Java工作原理 面向对象 对象 类 方法 继承 封装 多态 变量 常见面试题 Java简介 Java是一门面向对象编程语言 Jav
  • C++ 11 新特性之统一初始化语法

    C 之前的初始化语法很乱 有四种初始化方式 而且每种之前甚至不能相互转换 让人有种剪不断 理还乱的感觉 曾经去面试 就有人问我string有几种初始化方式 当时就说出了两种 fuck 面试官还得意的说 你连基本的初始化方式都记不清 还做啥2
  • Unable to correct problems, you have held broken packages无法安装libignition-math6-dev

    sudo apt get install libignition math6 dev 出现错误 Reading package lists Done Building dependency tree Reading state inform
  • C++ 抽象类

    抽象类 接口 接口描述了类的行为和功能 而无需完成类的特定实现 C 接口时通过抽象类实现的 设计抽象类的目的 是为了给其他类提供一个可以继承的适当的基类 抽象类本类不能被用于实例化对象 只能作为接口使用 注意 如果试图实例化一个抽象类的对象
  • 设计模式,简单工厂模式实现商场促销问题。

    前言 自始至终觉得编程是一门技术 更是一门艺术 不能只满足于写完代码运行后的结果完事 还应该让后人能读懂 容易修改 容易扩展和复用 又由于自己经常写出屎山代码 所以准备苦学设计模式 尽力写出更加优雅的代码 正文 问题引入 定义一个商场收银软
  • C++的文件操作open与close

    先看一下相应的打开文件的不同参数的作用 C open 打开文件 含打开模式一览表 打开模式可以用多个 但符号是 不是 注意啦 比如 ios in ios binary表示用二进制模式 以读取的方式打开文件 ios out ios binar
  • wchar_t char wstring string 项目转换

    wchar t char wstring string 项目转换 1 wchart t转wstring wchar t tmpRuleStr 10 0 wstring m tmpRuleStr wstring tmpRuleStr 2 ws
  • C++变量声明定义

    1 extern 声明变量 在一个文件里声明以后 表示该变量要去其它文件找变量 告诉编译器 你现在编译的文件中 有一个标识符虽然没有在本文件或本文件当前位置中定义 但是它是在别的文件中或本文件其它位置定义的全局变量 你要放行 声明变量 ex
  • STL标准模板库学习笔记三(STL哈希容器)

    关联式容器 排序 的底层实现采用的树存储结构 更确切的说是红黑树结构 无序容器 哈希 的底层实现采用的是哈希表的存储结构 基于底层实现采用了不同的数据结构 因此和关联式容器相比 无序容器具有以下 2 个特点 无序容器内部存储的键值对是无序的
  • c++通讯录管理系统

    系统需求 代码 include
  • 设计模式——简单工厂模式

    简单工厂模式定义为 简单工厂模式又称为静态工厂方法模型 它属于类创建型模式 在简单工厂模式中 可以根据参数的不同返回不同类的实例 简单工厂专门定义一个类来负责创建其他类的实例 被创建的实例通常都具有共同的父类 简单工厂模式结构图 简单工厂模

随机推荐

  • python中jupyter notebook安装教程、常用插件和拓展配置及基本使用(全面)

    文章目录 1 jupyter安装 2 jupyter常用插件配置 2 1 Jupyter Notebook和conda的环境和包管理工具nb conda 2 2 Jupyter Notebook扩展jupyter contrib nbext
  • c#基础知识---集合之排序列表(SortedList)

    SortedList 类代表了一系列按照键来排序的键 值对 这些键值对可以通过键和索引来访问 排序列表是数组和哈希表的组合 它包含一个可使用键或索引访问各项的列表 如果您使用索引访问各项 则它是一个动态数组 ArrayList 如果您使用键
  • 【Spring】AOP实例—日志模块的实现

    AOP实例 日志模块 AOP能够使系统服务 例如 日志模块 安全模块 事务管理 模块化 并以声明的方式将它们应用到它们需要影响的组件中去 使业务组件会具有更高的内聚性并且会更加关注自身的业务 完全不需要了解涉及系统服务所带来复杂性 日志模块
  • Java BufferImage图片处理(获取宽高、图片截取、转换灰度图)

    Java BufferImage图片处理 获取宽高 截取 转换灰度图 1 效果图 2 源码 参考 这篇博客将介绍如何使用Java读取图片为byte 数组 或者BufferedImage及互相转换 并进行了转换图片为灰度图 截取部分区域等 1
  • 电脑win+r命令大全

    0 osk 打开键盘 1 msconfig 关闭系统开机启动项 2 ipconfig all ipconfig release ipconfig renew 3 convert g fs ntfs 盘符格式转换 g代表U盘符 4 gpedi
  • DSS部署-完整版

    文章目录 DSS部署流程 第一部分 背景 第二部分 准备虚拟机 环境初始化 1 准备虚拟机 2 环境初始化 关闭防火墙 关闭selinux 关闭swap 根据规划设置主机名 在master添加hosts 将桥接的IPv4流量传递到iptab
  • 现在机器人是用什么语言编程

    现在机器人是用什么语言编程 对于很多的家长们来说 孩子的学习一直都是他们非常关心和重视的一件事情 很多的家长在培养孩子的学习方面也可以说是相当的认真的 他们会给孩子选择一些能够有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编程
  • 【搜索引擎Solr】Apache Solr 神经搜索

    Sease 1 与 Alessandro Benedetti Apache Lucene Solr PMC 成员和提交者 和 Elia Porciani Sease 研发软件工程师 共同为开源社区贡献了 Apache Solr 中神经搜索的
  • 【开发】前端工程——ReactJS

    前置知识 JavaScript ES6 ReactJS 前端开发的四个阶段 1 静态页面阶段 在第一个阶段中前端页面都是静态的 所有前端代码和前端数据都是后端生成的 前端纯粹只是增加一些特殊效果 后端MVC模式 Model 模型层 提供 保
  • 删除重复字符排序字符串(python3)

    问题描述 编写一个程序 从键盘接收一个字符串 然后按照字符顺序从小到大进行排序 并删除重复的字符 输入形式 从键盘输入一个字符串 以回车结束输入 要求程序可以处理含有空格的字符串 输出形式 程序接收此字符串 然后将其按照字符ASCII码值从
  • vue阶段思维导图

  • springboot 打印请求路径到 日志 控制台

    文章目录 application properties 添加 logging level org springframework web servlet mvc method annotation RequestMappingHandler
  • 安装双系统后,将windows设置为默认启动选项的方法

    原先的电脑只有windows系统 后来加装了ubuntu系统 但由于大部分时间仍然需要使用windows 但是默认启动项为ubuntu 难免会带来一些不便 将windows设为默认第一启动项的方法很简单 打开终端 查看grub的配置文件 s
  • VC++实用宏定义

    前言 在日常的编程工作中 常常定义一些实用的宏方便调用 该文章将收集一些常用的宏供大家参考 欢迎大家讨论和添加 指针释放 最常用的就是指针的安全释放 对应new的释放 ifndef ReleasePtr define ReleasePtr
  • File Processing by Python

    Go through all the file in destination path import os import sys def GetFileList dir fileList newDir dir if os path isfi
  • 【计算机网络】TCP协议

    实验目的 应用所学知识 1 熟悉 TCP 的协议格式 2 理解 TCP 对序列号和确认号的使用 3 理解 TCP 的流量控制算法和拥塞控制算法 实验步骤与结果 1 任务一 将Alice txt上传到服务器 使用wireshark捕获数据包
  • Windows平台的SDK、DDK与WDK

    尽管Windows平台的SDK DDK与WDK都包含了WinDBG工具包 但是用户获取WinDBG工具包的最主要方式还是从微软网站自由下载 因为这样获得的版本最新 最近尝试去了解WINDOWS下的驱动开发 现在总结一下最近看到的资料 1 首
  • 下采样与上采样

    一 下采样 概念 下采样 subsampled 又称为降采样 downsampled 可以通俗地理解为缩小图像 减少矩阵的采样点数 方法 1 最常用隔位取值 每行每列每隔k个点取一个点 2 合并区域 每 row k col k 窗口内所有像
  • python selenium 键盘操作 常用

    键盘事件 前面的 send keys 方法用来模拟键盘输入 keys 类提供了键盘上几乎所有按键的方法 组合键也是可以的 常用的键盘操作如下 send keys Keys BACK SPACE 删除键 BackSpace send keys
  • 三十、纯虚函数、抽象类、多态、简单工厂模式

    一 纯虚函数 虚函数是多态是实现多态的前提 如果我们需要在基类中定义共同的结构 那么接口就需要定义成虚函数 但是很多情况下基类的接口是无法实现的 比如形状类Shape 定义一个Draw方法 很明显这个方法没法实现 因为我们可以画出圆 正方形