C++虚函数与多态
C++ 虚函数与多态
Inheritance(继承)with virtual functions(虚函数)
non-virtual函数:你不希望derived class 重新定义(override,覆写)它
它已有默认定义。
pure virtual函数:你希望derived class 一定要重新定义(override,覆写)它,
你对他没有默认定义。
class Shape{ public: virtual void draw() const = 0; // pure virtual virtual void error(const std::string& msg); // impure virtual int objectID() const; // non-virtual ... }; class Rectangle:public Shape{...}; class Ellipse:public Shape{...};
形状为基类,子类为矩形,椭圆形,error()是打印错误信息的函数,那么设为虚函数的意义是,也许在子类中,我们不同的形状需要打印不同的错误信息,更为精确的错误信息的话,那么我们就可以在子类中去覆写error()函数,这样,在调用error()函数的时候调用的就是对应子类中的error()函数,那么draw()与error()有什么区别呢,可以看到 error()中是有默认操作的, const std::string& msg , 而draw()中是没有任何操作的(一般在函数原型后面加"=0"就意味着纯虚函数),这就是纯虚函数,如果父类中的一个函数为纯虚函数的话,那么这个函数是必须在子类中去覆写的。
Inheritance(继承) with virtual
Template Method 模板方法
CDocument::
OnFileOpen()
{
...
Serialize()
...
};
class CMyDoc: public CDocument { virtual Serialize(){...} };
main()
{
CMyDoc myDoc;
...
myDoc.OnFileOpen();
}
模板方法具体就是定义一个模板结构,将具体内容延迟到子类去实现。(基于"继承")
在main中,我们通过子类对象myDoc调用父类中的函数OnFileOpen(),打开一个文件,
进入到OnFileOpen()中,首先执行了打开所有文件都需要进行的操作,然后具体打开操作需要在
Serialize()中实现,但每个应用如何打开只有对应的应用才知道,所以在子类中覆写 Serialize()方法,这样在OnFileOpen()中的Serialize()调用的其实是子类中的Serialize()方法,
灵活性也大大提高了。
模拟过程
#include <iostream> using namespace std; class CDocument { public: void OnFileOpen() { //每个cout 输出代表一个实际动作 cout << "dialog..." <<endl; cout << "check file status..." <<endl; cout << "open file..."<<endl; Serialize(); cout << "close file..." <<endl; cout << "update all views..."<<endl; } virtual void Serialize() {}; }; class CMyDoc: public CDocument { public: virtual void Serialize() { //只有应用程序知道如何读取自己的文件格式 cout << "CMyDoc::Serialize()" <<endl; } }; int main() { CMyDoc myDoc; //假设对应[File/Open] myDoc.OnFileOpen(); }