多态性与将实现多态的函数的访问限定符没有任何关系,private 函数仍然可以实现多态,它的指针仍然位于vtbl中,只不过该函数的多态一般只能在基类的内部由其他非虚函数调用该函数的时候反映出来,访问限定符仅仅限制外部对类的成员的访问权限,它并没有破坏以下规则

通过基类指针或引用调用成员函数时,如果该函数时非虚的,那么将采用静态绑定,即编译时绑定;如果该函数是虚拟的,则采用动态绑定,即运行时绑定。

#include <string>
#include <iostream>
using namespace std ; class Base
{
private:
virtual string classID() const
{
return string("Base") ;
} protected:
virtual void doWork() = ; // 纯虚函数 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 ;
}
}; int main()
{
Base* bp = new DerivedA() ;
bp->work() ;
delete bp ;
}

运行结果:
this class id is DerivedA
this is DerivedA doWork !

虽然ClassID是private,但是还是实现了多态(和将这个函数声明为public的结果是一样的)。因为这个函数是virtual的。用基类指针或引用进行虚函数调用采用的是动态绑定,看看编译器为调用classID产生的代码就知道了:

//c++伪码

(this->vptr[1])() ;

在运行时期,通过this指针将会找到正确的vtbl,即DerivedA类的vtbl,这样自然就会出现上面的结果了。那么将classID 声明为private限制了什么?和将非虚函数声明为private一样,这将使得在Base类外部无法调用多态函数classID,只能在Base内部调用,如通过work函数调用。

参考:http://www.dewen.io/q/8738/%E7%A7%81%E6%9C%89%E7%BA%AF%E8%99%9A%E5%87%BD%E6%95%B0%E7%9A%84%E4%BD%9C%E7%94%A8%EF%BC%9F

------------------------------------------------------------------------------

新的意见:

我觉得这的确是c++本身矛盾的地方,就像它的多重继承一样,在我看来对private函数设成虚函数有点紊乱,当然例子只是一个demo罢了,说明了问题,但在实际运用中我觉得private设为虚函数很不符合,我的论据是java:

在java中,public,protected,friendly函数自动可以多态的(不用加什么virtual之类的词),但是有种情况不可以,当函数设为private的时候,就已经隐藏申明是final的了,final就是不允许它被子类改写,所以拒绝多态。大家不懂java没关系,我就是说java作为比c++更加符合oo的语言,去掉private函数的多态性肯定有它的道理的。

参考:http://bbs.csdn.net/topics/60083939

public class Polymorphism {
private void show()
{
print("show parent");
}
public static void main(String[] args)
{
Polymorphism p=new privateMethod();
p.show();
}
}
class privateMethod extends Polymorphism
{
public void show()
{
print("show derived");
}
}

输出结果:结果是 show parent。Java里面是不能重写私有方法的,这个其实很好理解,因为私有方法在子类是不可见的。子类没有继承父类的私有方法,更谈不上重写了。因此在子类中的同名方法是一个全新的方法。

参考:http://www.cnblogs.com/developerY/p/3421711.html

最新文章

  1. Python 操作 MongoDB
  2. 腾讯sdk学到了
  3. hdu----(4513)吉哥系列故事——完美队形II(manacher(最长回文串算法))
  4. 【BZOJ】【2938】【POI2000】病毒
  5. java应用程序利用Exe4j打包exe文件
  6. 使用appium做安卓手机web自动化测试 真机demo
  7. 关于懒加载(lazy loading)
  8. poj1054The Troublesome Frog
  9. Android应用换肤总结
  10. Ant快速入门(四)-----Ant的任务(Task)
  11. 使用angular4和asp.net core 2 web api做个练习项目(四)
  12. [原创]消灭eclipse中运行启动的错误:“找不到或无法加载主类”问题
  13. Windows下快速建立cocos2d-x项目
  14. Vue note 2
  15. 监控MySQL组复制
  16. 物联网架构成长之路(24)-Docker练习之Compose容器编排
  17. JAVA动手动脑及课后作业
  18. bootstrap框架中data-toggle=&quot;tab&quot;属性会取消a标签默认行为
  19. poj 3164 Command Network(最小树形图模板)
  20. svn 教程

热门文章

  1. 四、VMware Tools 安装 与 问题
  2. C++ this指针详解
  3. 网络笔记02数据解析 -1-JSON解析
  4. P3408: [Usaco2009 Oct]Heat Wave 热浪
  5. 时间日期设置--ctime头文件
  6. 老周的ABP框架系列教程 -》 一、框架理论初步学习
  7. 三、freemarker数据、模版指令
  8. Python字符编码详解
  9. Codeforces Round #349 (Div. 1) B. World Tour 最短路+暴力枚举
  10. 以前用过Extjs技术的开发人员在学习Extjs4时需要注意的问题