以下是我从网络上摘录下来的,感觉看完这些精华讨论估计对虚函数和纯虚函数也理解差不多了。。。
1.虚函数
参考书籍: COM本质论 侯捷老师的 深入浅出MFC
疑问1:
若是为了继承,那么普通的类(没有虚函数,纯虚函数)就可以被继承,而且工作的相当好.虚函数倒是可以理解,应该是可以通过,一个指向基类对象的指针能够依据实际的指向,来调用不同的函数,实现多态.而纯虚函数难道就是为了实现接口?接口存在的意义,我实在弄不懂,我干嘛要预先定义好?未来的事情本难料就等有一天我的类中需要使用某个函数,在添加一个函数不久可以?
疑问2:
为什么要用虚函数,仅仅是为了子类可以重写它吗?不是虚函数我也可以重写它呀?派生类中和基类中有同签名函数,通过派生类对象访问这个函数时,应该优先执行派生类的函数,如果派生类没有这个函数才去执行基类中这个同名函数(公有继承时)。
上述可能是大部分深入学习C++朋友的典型疑惑.
用具体例子回答:
例子1:
有纯虚函数的类是不可能生成类对象的,如果没有纯虚函数则可以。
class CA
{
public:
virtual void fun() = 0; // 说明fun函数为纯虚函数
virtual void fun1();
};
class CB
{
public:
virtual void fun();
virtual void fun1();
};
// CA,CB类的实现
...
void main()
{
CA a; // 不允许,因为类CA中有纯虚函数
CB b; // 可以,因为类CB中没有纯虚函数
...
}
例子2:
"每本书"都有作者,每本书都是都从抽象基类"书"继承而来
然而"书"没有作者,所以我们"书"为定义一个纯虚函数“作者”
这意味着"书"不能被实例化,但是可以通过"书"的指针枚举每本书的作者!
但如果这些"作者"有一些共同的属性,我们可以把它写进基类,这是就成了虚函数!
从功能上讲,无论虚函数和纯虚函数都可以达到同样的目的。
但是纯虚函数可以使结构更清楚一些。
纯虚函数可以保证子类必须实现自己的函数(这是一种强制手段),而虚函数则不保证。
如果在虚函数的情况下,你可以继承一个基类,而不重载该函数(这可能是你故意的,也
有可能是你无意中忘记了),编译器不知道你的意图。有了纯虚函数,则可保证重要的函数
必须被重新定义。
你要生一个孩子,
首先,你要定义一个人,
这个人不是谁谁谁,
然后这个人的所有功能都预定义,不过都没有实现,但是大家知道他是一个人,否则他就是不是人。
接着,还是生出来了,
他便实现了人的所有功能,
呵呵,纯虚函数就是这样的。
在《COM技术内幕》上抄来的,可能有用:
"...(实现继承)使得一个对象的实现同另一个对象的实现紧紧的关联起来。在这种情况下,当基类的实现被修改之后,派生类将无法正常运行而必须被修改。对于一个中等规模的c++程序而言,这或许并不成问题,因为在这种情况下,我们一般能够获得所有的源代码,也能够对所有的派生类进行修改。但是对于较大的c++程序而言,对受影响的派生类进行修改所花费的时间将是相当长的。更糟的是,我们可能根本无法得到所有的源代码。这就是为什么一些用c++编写大型程序的专家们强烈建议人们基于抽象基类来构建应用程序的原因。"
例子3:
比如你要设计类库
基类是“形状”
class 形状
{
virtual draw() = 0;
}
这个时候你是无法实现draw函数的,因为你不知道是什么样的形状?
好了,现在可以派生了
class 园 : public 形状
{
virtual draw(int radius);
}
class 矩形 : public 形状
{
virtual draw(int x, int y);
}
到了子类就可以具体实现了。你可能会说不定义“形状”类,直接定义“园“和“矩形"类得了。
但是,有了形状类整个代码就清晰了,所用的画的函数都是draw,而不是drawcircle, drawrectangle等等。
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/my_c_s_d_n/archive/2010/04/13/5480008.aspx