C++学习25 纯虚函数和抽象类
在C++中,可以将成员函数声明为纯虚函数,语法格式为:
virtual 函数返回类型 函数名 (函数参数) = ;
纯虚函数没有函数体,只有函数声明,在虚函数声明结尾加上=0,表明此函数为纯虚函数。
最后的=0并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”。
包含纯虚成员函数的类称为抽象类(Abstract Class)。之所以说它抽象,是因为它无法实例化,也就是无法创建对象。原因很明显,纯虚函数没有函数体,不是完整的函数,无法调用,也无法为其分配内存空间。
抽象类通常是作为基类,让派生类去实现纯虚函数。派生类必须实现纯虚函数才能被实例化。
纯虚函数使用举例:
#include <iostream>
using namespace std;
//线
class Line{
protected:
float len;
public:
Line(float len): len(len){}
virtual float area() = ;
virtual float volume() = ;
};
//矩形
class Rec: public Line{
protected:
float width;
public:
Rec(float len, float width): Line(len),width(width){}
float area(){ return len*width; }
};
//长方体
class Cuboid: public Rec{
protected:
float height;
public:
Cuboid(float len, float width, float height): Rec(len, width), height(height){}
float area(){ return *(len*width + len*height + width*height); }
float volume(){ return len*width*height; }
};
//正方体
class Cube: public Cuboid{
public:
Cube(float len): Cuboid(len, len, len){}
float area(){ return *len*len; }
float volume(){ return len*len*len; }
};
int main(){
Line *p = new Cuboid(, , );
cout<<"The area of Cuboid is "<<p->area()<<endl;
cout<<"The volume of Cuboid is "<<p->volume()<<endl; p = new Cube();
cout<<"The area of Cube is "<<p->area()<<endl;
cout<<"The volume of Cube is "<<p->volume()<<endl;
return ;
}
本例中定义了四个类,它们的继承关系为:Line --> Rec --> Cuboid --> Cube。
Line 是一个抽象类,也是最顶层的基类,在 Line 类中定义了两个纯虚函数 area() 和 volume()。
在 Rec 类中,实现了 area() 函数;所谓实现,就是定义了纯虚函数的函数体。但这时 Rec 仍不能被实例化,因为它没有实现继承来的 volume() 函数,volume() 仍然是纯虚函数,所以 Rec 也仍然是抽象类。
直到 Cuboid 类,才实现了 volume() 函数,才是一个完整的类,才可以被实例化。
可以发现,Line 类表示“线”,没有面积和体积,但它仍然定义了 area() 和 volume() 两个纯虚函数。这样的用意很明显:Line 类不需要被实例化,但是它为派生类提供了“约束条件”,派生类必须要实现这两个函数,完成计算面积和体积的功能,否则就不能实例化。
在实际开发中,你可以定义一个抽象基类,只完成部分功能,未完成的功能交给派生类去实现(谁派生谁实现)。这部分未完成的功能,往往是基类不需要的,或者在基类中无法实现的。虽然抽象基类没有完成,但是却强制要求派生类完成,这就是抽象基类的“霸王条款”。
抽象基类除了约束派生类的功能,还可以实现多态。请注意代码第 39 行,指针 p 的类型是 Line,但是它却可以访问派生类中的 area() 和 volume() 函数,正是由于在 Line 类中将这两个函数定义为纯虚函数;如果不这样做,39行后面的代码都是错误的。我想,这或许才是C++提供纯虚函数的主要目的。
关于纯虚函数的几点说明:
1) 一个纯虚成员函数就可以使类成为抽象基类,但是抽象基类中除了包含纯虚成员函数外,还可以包含其它的成员函数(虚函数或普通函数)和成员变量。
2) 只有类中的虚函数才能被声明为纯虚成员函数,普通成员函数和顶层函数均不能声明为纯虚函数。如下例所示:
//顶层函数不能被声明为纯虚函数
void fun() = ; //compile error
class base{
public :
//普通成员函数不能被声明为纯虚函数
void display() = ; //compile error
};
C++学习25 纯虚函数和抽象类的更多相关文章
- C++学习基础十二——纯虚函数与抽象类
一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...
- C++ //纯虚函数和抽象类 // 语法 virtual 返回值类型 函数名 (参数列表)=0 //当类中有了纯虚函数 这个类也称为抽象类
1 //纯虚函数和抽象类 2 // 语法 virtual 返回值类型 函数名 (参数列表)=0 3 //当类中有了纯虚函数 这个类也称为抽象类 4 5 6 #include <iostream& ...
- C++基础(纯虚函数与抽象类)
C++基础之纯虚函数与抽象类 引言 纯虚函数在C++编程中的地位很重要,其关联到了设计模式中"接口"的概念. 语法 纯虚函数的语法: 1. 将成员函数声明为virtual 2. ...
- C++:纯虚函数与抽象类
5.4.3 纯虚函数和抽象类 纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但是要求在派生类中根据需要对它进行定义,或仍然说明为纯虚函数. 声明纯虚函数的一般格式是: virtual 函数 ...
- c++,纯虚函数与抽象类
1.纯虚函数的定义: (1)虚函数被“初始化”为0的函数.声明纯虚函数的一般形式是virtual 函数类型 函数名(参数表列) =0;(2)纯虚函数没有函数体:(3)最后面的“=0”并不表示函数返回值 ...
- C++复习:纯虚函数和抽象类
纯虚函数和抽象类 1基本概念 2抽象类案例 3抽象类在多继承中的应用 C++中没有Java中的接口概念,抽象类可以模拟Java中的接口类.(接口和协议) 3.1有关多继承的说明 工程上的多继承 被 ...
- 简单地说, cpp中的纯虚函数就是抽象类的具体实现
简单地说, cpp中的纯虚函数就是抽象类的具体实现.包含了纯虚函数的类就是抽象类.
- C++基础 (7) 第七天 多态的原理 纯虚函数和抽象类 依赖倒置原则
1 昨日回顾 2 多态的原理 1 要有继承 2 要有子类重写父类的虚函数 3 父类指针(或者引用)指向子类对象 (动态联编 虚函数表 3 证明vptr指针的存在 4 vptr指针在构造父类的时候是分步 ...
- c++-纯虚函数和抽象类
纯虚函数和抽象类 C面向接口编程和C多态 函数类型语法基础 函数指针做函数参数(回调函数)思想剖析 函数指针做函数参数两种用法(正向调用.反向调用) 纯虚函数 抽象类 抽象类基本概念 抽象类在多继承中 ...
随机推荐
- 斐波那契数列PHP非递归数组实现
概念: 斐波那契数列即表达式为 a(n) = a(n-1)+a(n-2) 其中 a1 =0 a2 = 1 的数列 代码实现功能: 该类实现初始化给出n,通过调用getValue函数得出a(n)的值 ...
- CSQuery 简单测试
1. 使用环境 vs2010 ,csquery 2. 测试的内容 学习了解csquery 3. 代码 添加csquery 的就不用写了 测试的例子是获取我的博客的信息,使用webbrowser 控件 ...
- 内联样式自动出现,一般是js控制写入的
内联样式自动出现,一般是js控制写入的
- NET 2.0 OCR文字识别技术(Tesseract 引擎)[转]
一.OCR简介 参见http://baike.baidu.com/view/17761.htm?fr=ala0_1 大家参照,我第一次也是这么了解的,呵呵.高手见笑 现在市面上好多OCR 引擎,不 ...
- 【redis】 linux 下redis 集群环境搭建
Redis集群 (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下) 127.0.0.1:63791 ...
- phonegap–app启动欢迎引导页localstorage
对一个新的app,一般情况都会添加一个介绍和欢迎的页面来告诉用户app的功能和新的特性. 那么在phonegap项目里面如何添加这样个引导欢迎页. 这里需要注意的是只有app第一次打开的时候才会有,其 ...
- js 如何生成二维数组
想了几种方法都不能很好的,用js定义二维数组.这种定义,指的是:定义按需确认数组大小. 网上看了下,都是用for循环创建,大小必须提前设定.不是我想要的.(感觉不能和php一样,真是麻烦!) 先贴出代 ...
- JQuery移除事件
移除事件 unbind(type [,data]) //data是要移除的函数 $('#btn').unbind("click"); //移除click $('#btn') ...
- 关于css中列表(ul ol)存在默认间距的问题
一.总结: 有时候我们要给列表(ul ol 本身就是属于块级元素)的上表框或下边框设置颜色,如下: 但是在给内联块级元素(inline-block)的上表框或下边框设置颜色的时候,就没有这么简单: 在 ...
- 【java基础学习-2--】关于Hashcode()的使用
摘要 Java中equals()和hashCode()有一个契约: 如果两个对象相等的话,它们的hash code必须相等: 但如果两个对象的hash code相等的话,这两个对象不一定相等; 这个约 ...