纯虚函数

C++ 接口(抽象类)

风格不统一 提交于 2019-12-13 16:25:38
C++ 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。 C++ 接口是使用 抽象类 来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示: class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; 设计 抽象类 (通常称为 ABC)的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为 接口 使用。如果试图实例化一个抽象类的对象,会导致编译错误。 因此,如果一个 ABC 的子类需要被实例化,则必须实现每个虚函数,这也意味着 C++ 支持使用 ABC 声明接口。如果没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。 可用于实例化对象的类被称为 具体类 。 抽象类的实例 请看下面的实例,基类 Shape 提供了一个接口 getArea() ,在两个派生类 Rectangle 和 Triangle 中分别实现了 getArea() : #include

案例分析:设计模式与代码的结构特性

一个人想着一个人 提交于 2019-12-07 18:43:28
我选择的软件设计模式为策略模式(strategy pattern) 一、策略模式 意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。 主要解决: 在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。 何时使用: 一个系统有许多许多类,而区分它们的只是他们直接的行为。 如何解决: 将这些算法封装成一个一个的类,任意地替换。 关键代码: 实现同一个接口。 应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。 优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。 使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。 注意事项: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。 二、引用关键代码解释该设计模式在该应用场景中的适用性

什么情况下应用纯虚类

天大地大妈咪最大 提交于 2019-12-07 07:01:43
前几天跟同事brainstorm,讨论一个关于纯虚类的使用问题,挺有意思。回来心中久久不能平静,写出来一吐为快。 不论在C++中还是C#中,纯虚类都是不能实例化的,这是因为纯虚类其实是一个对业务类型的一种高度抽象,本质上是不存在这种东西的,所以也就不能实例化它。对于C++中只要类中含有一个纯虚函数就是纯虚类,而C#中是abstract修饰的类就是纯虚类,即使类中没有虚方法也可以是纯虚类,在这里我觉得C#的纯虚类没有C++的严谨,如果纯虚类中没有纯虚方法的话,那有何意义。 明白了纯虚类的原理,那纯虚类应该肯定需要被别的类继承的,因为如果不继承的话,它自己本身也不能实例化,就没有存在的意义了,所以它肯定是需要被继承的。那它需不需要含有一个或者多个纯虚方法呢?答案是肯定的,因为既然纯虚类是需要被继承的,那没有纯虚方法又有何意义。没有纯虚方法它就应该是可以实例化的,那就没有必要将其设定为纯虚类的,这也是我吐槽C#的abstract的一个原因。 有了纯虚类一定要有纯虚方法的这个基础,那就可以想象纯虚类的业务场景应该是下面这个样子的 abstract class Goods { public int GetPrice() { int price = 0; //do some standard things price = this.CaculatePrice(); //do some

析构函数可以是纯虚函数

℡╲_俬逩灬. 提交于 2019-12-07 07:01:12
在某些类里声明纯虚析构函数很方便。纯虚函数将产生抽象类——不能实例化的类(即不能创建此类型的对象)。有些时候,你想使一个类成为抽象类,但刚好又没有任何纯虚函数。怎么办?因为抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函 数。  class awov {   public:   virtual ~awov() = 0; // 声明一个纯虚析构函数   }; 这个类有一个纯虚函数,所以它是抽象的,而且它有一个虚析构函数,所以不会产生析构函数问题。但这里还有一件事:必须提供纯虚析构函数的定义:   awov::~awov() {} // 纯虚析构函数的定义 这个定义是必需的,因为虚析构函数工作的方式是:最底层的派生类的析构函数最先被调用,然后各个基类的析构函数被调用。这就是说,即使是抽象类,编译器也要产生对~awov的调用,所以要保证为它提供函数体。如果不这么做,链接器就会检测出来,最后还是得回去把它添上。 虽然抽象类的析构函数可以是纯虚函数,但要实例化其派生类对象,仍必须提供抽象基类中析构函数的函数体。 抽象类的纯虚函数的实现可以由自身给出,也可以由派生类给出。错了,除了析构函数外,其他函数都不行,必须要在派生类中进行实现。 来源: CSDN 作者: sunshinewave 链接: https:/

C++纯虚函数定义

旧街凉风 提交于 2019-12-07 06:54:10
看代码时时无意看到代码里某类的纯虚函数居然有实现,吓我一跳,果真学无止境啊! 在此转载相关文章一篇,以便遗忘: https://blog.csdn.net/happymawolf/article/details/6369585 今天,我读到《effective c++》的第34条款,里面竟然提到纯虚函数也是可以定义的,大吃一惊,赶快打开vs2005,自己编写了一段代码,编译运行,发现竟然真的可以! 俺的代码: class A { public: virtual void pureVirtualFunc() = 0; }; void A::pureVirtualFunc() { cout << "I'am pureVirtualFunc" << endl; } class B : public A { public: void pureVirtualFunc() { A::pureVirtualFunc(); cout << "I belong to B!"; } }; int main(void) { B b; b.pureVirtualFunc(); return 0; } 运行结果: I’am pureVirtualFuncI belong to B!请按任意键继续. . . 原来抽象类是可以对纯虚函数进行定义的,在其子类中也是可以使用抽象父类的缺省实现

第52课.c++中的抽象类和接口

徘徊边缘 提交于 2019-12-06 14:14:02
1.什么是抽象类 a.可用于表示现实世界中的抽象概念 b.是一种只能定义类型,而不能产生对象的类 c.只能被继承被重写相关函数 (不能创建对象,只能用于继承,可以用来定义指针) d.直接特征是 相关函数没有完整的实现 2.抽象类与纯虚函数 a.c++语言中没有抽象类的概念 b.c++中通过纯虚函数实现抽象类 c.纯虚函数是指只定义原型的成员函数 d.一个c++类中只要存在纯虚函数这个类就成为了抽象类 eg. 纯虚函数语法规则: class Shape { public: virtaul double area () = 0; }; //这里" = 0"用于告诉编译器当前是声明纯虚函数,因此不需要定义函数体 eg: #include <iostream> #include <string> using namespace std; class Shape { public: virtual double area () = 0; }; class Rect : public Shape { int ma; int mb; public: Rect (int a, int b) { ma = a; mb = b; } double area () { return ma * mb; } }; class Circle : public Shape { int mr; public:

C++ 基础语法 快速复习笔记(3)---重载函数,多态

流过昼夜 提交于 2019-12-06 07:47:20
1.重载运算符和重载函数: C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。 当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。 选择最合适的重载函数或重载运算符的过程,称为重载决策。 a.函数重载: 在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。 b.运算符重载: 您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。 重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。 详细例子: https://www.runoob.com/cplusplus/cpp-overloading.html 2.多态: 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 例子: https://www.runoob

C++8种常见类类型

匿名 (未验证) 提交于 2019-12-02 23:40:02
版权声明:转载请注明出处,十分感谢! https://blog.csdn.net/qq_30683329/article/details/91473331 C++8种常见类类型 前言 大部分面向对象开发工作中都应用了以下部分或者全部的基本类别的类: 1、具体类(concrete class) 2、抽象类(abstract class) 3、接口类(interface class) 4、节点类(node class) 5、支持类(support class) 6、域类(domain class) 7、应用类(utility class) 8、集合和容器类(collection and container class) 这些类并不是特定的语言结构,而是用于实现逻辑类的技术。 类类型 描述 具体类 独立类;表示一个祖先-后代世系终止的结束类 抽象类 为所有的子类提供布局和蓝图的基准类,不能声明此类的对象;必须派生新的类,对抽象的基本中声明任何虚函数提供定义 接口类 用于修改或者增强另外一个类得接口,为了非面向对象代码和数据,提供面向对象性,而用来封装独立函数 节点类 提供了继承和多态的基础;不包含纯虚函数 域类 创建类在指定域内部模拟部分现实或者实体 支持 /应用类 不管在任何域内,对于不同的应用都非常有用 集合和容器类 其他对象组的一般性容纳器 具体类 具体类是作为结束类而设计和实现的

详谈C++中的多态

和自甴很熟 提交于 2019-12-02 11:32:06
详谈C++中的多态 1.多态基本概念 多态是面向对象程序设计语言中数据抽象和继承之外的第三个基本特征。多态性(polymorphism)提供接口与具体实现之间的另一层隔离,从而将”what”和”how”分离开来。 c++支持编译时多态(静态多态)和运行时多态(动态多态),运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态。 //计算器 class Caculator{ public: void setA(int a){ this->mA = a; } void setB(int b){ this->mB = b; } void setOperator(string oper){ this->mOperator = oper; } int getResult(){ if (this->mOperator == "+"){ return mA + mB; } else if (this->mOperator == "-"){ return mA - mB; } else if (this->mOperator == "*"){ return mA * mB; } else if (this->mOperator == "/"){ return mA / mB; } } private: int mA; int mB; string mOperator; };