纯虚函数能为private吗?

发表于:2012-12-18 10:26

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
DotNet
分享:

  我们把一个仅仅含有纯虚函数的类称为接口,我们也好像已经习惯了将这个接口中的所有纯虚函数全声明为public,而且按照这样的设计,一切都工作得不错。比如COM正是这样做的,它的接口中几乎不会存在private的纯虚函数。那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的,那么什么时候可以将(纯)虚函数设为private了?这些都是本文将要讨论的主题。一起来看看。

  一、访问限定符与继承

  如果基类隐式(间接)向子类暴露了私有成员,那么从某种意义上讲,该私有成员对于子类是可见的。

  任何一本讲C++基础的课本上都详细地介绍了访问限定符与继承的关系,在这里就不重复了,但是,课本上的东西并不全,不信?那么请先看看下面的例子:

#include <string> 
#include <iostream>
using namespace std ;

class Base
{
private:
    string classID() const
    {
       return string("Base") ;
    }

protected:
    virtual void doWork() =0 ; //纯虚函数

public: 
    void work()
    {
        cout<<"this class id is "<<classID()<<endl ; 
        doWork() ;
    }

    virtual ~Base()
    {
    }
};

class DerivedA : public Base
{
private:
    string classID() const 
    {
       return string("DerivedA") ;
    }

protected:
    void doWork()
    {

       cout<<"this is DerivedA doWork !"<<endl ;
    }
};

  以上的代码声明了一个基类和一个子类,不过比较奇特的是基类的提供的公共接口是非虚的,而这个非虚的公共接口却调用了一个非虚的私有函数和一个虚拟的保护函数。接着,子类重定义了这两个函数。那么下面的调用会输出什么了?

Base* bp = new DerivedA();
bp->work();
delete bp ;

  以下是输出的结果:

this class id is Base
this is DerivedA doWork!

  怎么回事?为什么不是

this class id is DerivedA
this is DerivedA doWork!

  子类的classID()不是将基类的classID()覆盖了么?我们来分析一下,基类中的公共的work()成员函数调用了私有的classID()成员函数,根据输出的结果来看,在子类中定义的classID方法并没有覆盖基类的同名方法,为什么呢?难道是因为classID是private导致的?那好,我们将classID函数改为public再次运行,我们期望的结果出现了吗?呵呵,很抱歉,没有,希望再次破灭了,为什么会这样?这主要涉及的原因是:普通函数的调用是在编译期确定的,当work函数一看到所调用的classID是非虚的,就会毫无疑问地去直接使用基类的classID。这一切与Base类是否会被继承没有任何关系,跟Base类被继承后子类会否再次定义classID就更没有关系了。

31/3123>
100家互联网大公司java笔试题汇总,填问卷领取~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号