C++抽象类和纯虚函数
如果是这种情况,那么 C++ 语言允许程序员将该函数声明为一个纯虚函数,也就是,一个在类中没有提供实现的成员函数。C++ 声明一个纯虚函数的方法是将表达式 =0 放在类声明中,而函数的主体则不存在。
例如,如果要将一个成员函数 void draw() 声明为纯虚函数,那么它的类中的声明语句示例如下:
void draw()= 0;
纯虚函数有时称为抽象函数,而如果某个类至少有一个纯虚函数,那么它将被称为抽象类。C++ 编译器不允许实例化一个抽象类。抽象类只能被子类化,也就是说,只能使用它们作为派生其他类的基类。
派生自抽象类的类将继承基类中的所有函数,除非它覆盖继承的所有抽象函数,否则它本身也是抽象类。抽象类的用处在于它定义了一个接口,接口必须由从它派生的所有类的对象来支持。
可以把抽象类看作一个除子类外没有实例的类。现实生活中有许多抽象类的例子。例如,在动物王国中, 动物 类就是所有动物的抽象类。所有动物的实例(例如狗、鸡、狐狸等)都属于 动物 抽象类中的某个子类,但 动物 本身不能实例化。
现在来看一看由一个形状的集合组成的图形系统,这些形状必须绘制在屏幕的某些位置上。每个形状对象都有一些成员变量来记录它的位置,并且还有一个成员函数,用于在正确位置绘制形状。该系统支持的不同形状可能包括矩形、六边形和其他形状。
因为矩形是一个形状,而六边形也是一个形状,所以单独创建一个 Shape 类是有意义的,然后就可以从 Shape 类中派生出 Rectangle 类和 Hexagon 类。Shape 类有一个成员函数 setPosition,将用于设置形状的位置;还有一个成员函数 Draw,用于绘制形状。但是,由于 Shape 是一个抽象类(没有任何形状可以是一个笼统概念上的 形状 ,它必须是矩形、六边形、三角形或其他具体的形状),绘制一个特定形状的逻辑必须委托给一个合适的子类,因此,draw() 函数不能在 Shape 类中实现,必须将它声明为一个纯虚函数。
下面的程序演示了上述 Shape 类,它具有两个派生类:Rectangle 和 Hexagon。该类声明了一个纯虚函数 draw(),该函数将由其两个子类实现。main 函数使用了一个指针矢量来维护一个 Shape 对象的集合。
// This program demonstrates abstract base // classes and pure virtual functions. #include iostream #include memory #include vector using namespace std; class Shape protected: int posX, posY; public: virtual void draw() const =0; void setPosition(int pX, int pY) posX = pX; posY = pY; class Rectangle : public Shape public: virtual void draw() const cout Drawing rectangle at posX posY endl; class Hexagon : public Shape public: virtual void draw() const cout Drawing hexagon at posX posY endl; int main() // Create vector of pointers to Shapes of various types vector shared_ptr Shape shapes make_shared Hexagon (), make_shared Rectangle (), make_shared Hexagon () // Set positions of all the shapes int posX = 5, posY = 15; for (int k = 0; k shapes.size (); k++) shapes[k]- setPosition(posX, posY); posX += 10; posY += 10; // Draw all the shapes at their positions for (int j =0; j shapes.size (); j++) shapes[j]- draw(); return 0; }
程序输出结果:
Drawing hexagon at 5 15
Drawing rectangle at 15 25
Drawing hexagon at 25 35
此程序提供了动态绑定和多态的另一个示例。来看以下声明:
shapeArray[j]- draw();
它将在循环中执行不同的次数。
for (int j = 0; j shapes.size (); j ++) shapeArray[j]- draw(); }
第一次执行语句时,它将调用六边形对象的 draw 函数;而第二次执行时,它将调用矩形对象的 draw 函数。因为这两个 draw 函数是在不同的类中,所以它们会产生不同的行为。
关于抽象基类和纯虚函数,请记住以下知识要点:
相关文章
- c++ offsetof_函数offset的用法
- c++实现skipList「建议收藏」
- cout是c++还是c_c语言中cout的用法
- 刨析一下C++构造析构函数能不能声明为虚函数的背后机理?
- C++级联函数调用
- C++最佳实践 | 3. 安全性
- C++基础——C++面向对象之类、对象与继承基础总结(类和对象概念、构造函数与析构函数、this指针、继承)
- C++ STL 标准模板库(排序/集合/适配器)算法
- C++ 矩阵运算库 Eigen
- C++基础——C++面向对象之重载与多态基础总结(函数重载、运算符重载、多态的使用)
- C++模板扩展
- C++函数模板与类模板
- 【C++】哈希应用:位图 哈希切分 布隆过滤器
- Linux老是提示compat-libstdc++ is not installed的原因详解程序员
- C++函数对象详解(附带实例)
- C++静态成员变量和静态成员函数详解
- C++常对象和常成员函数详解
- C++11 Lambda表达式(匿名函数)详解
- C++11右值引用详解
- C++ strcpy:字符串赋值函数
- C++ tellg和tellp函数用法详解
- 泛型是什么,C++泛型编程又是什么?
- 21天速成 C++?编程生涯的一点思考
- C++概念重载、覆盖、隐藏的使用说明
- C++实现两个日期间差多少天的解决方法
- 基于C++list中erase与remove函数的使用详解
- 深入探讨C++父类子类中虚函数的应用
- 探讨:C++中函数返回引用的注意事项
- c++中的string常用函数用法总结
- C语言/C++中如何产生随机数
- C++指针数组、数组指针、数组名及二维数组技巧汇总
- C++虚函数表实例分析