私有虚函数的特点(C++和Java的机制还有所不同)
多态性与将实现多态的函数的访问限定符没有任何关系,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
私有虚函数的特点(C++和Java的机制还有所不同)的更多相关文章
- TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)
手工找出来,对比一下,有助于VCL框架的理解.----------------------------------------------------------------------------- ...
- JAVA – 虚函数、抽象函数、抽象类、接口
本文转载地址:http://blog.csdn.net/trojanpizza/article/details/6556604 1. Java虚函数 虚函数的存在是为了多态. C++中普通成员函数加 ...
- 【转】JAVA – 虚函数、抽象函数、抽象类、接口
1. Java虚函数 虚函数的存在是为了多态. C++中普通成员函数加上virtual关键字就成为虚函数 Java中其实没有虚函数的概念,它的普通函数就相当于C++的虚函数,动态绑定是Java的默认行 ...
- C++的抽象类、虚函数、虚基类和java的抽象类和接口
简单整理如下: C++虚函数 == java普通函数 C++纯虚函数 == java抽象函数 C++抽象类 == java抽象类 C++虚基类(全都是纯虚函数) == java接口
- Java C++ 比较 – 虚函数、抽象函数、抽象类、接口
[转自]原文 Java – 虚函数.抽象函数.抽象类.接口 1. Java虚函数 虚函数的存在是为了多态. C++中普通成员函数加上virtual关键字就成为虚函数 Java中其实没有虚函数的概念,它 ...
- C++学习基础十二——纯虚函数与抽象类
一.C++中纯虚函数与抽象类: 1.含有一个或多个纯虚函数的类成为抽象类,注意此处是纯虚函数,而不是虚函数. 2.如果一个子类继承抽象类,则必须实现父类中的纯虚函数,否则该类也为抽象类. 3.如果一个 ...
- 多态性&& 虚函数 && 抽象类
http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/11/2134673.html 多态性 指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动 ...
- 你好,C++(37)上车的人请买票!6.3.3 用虚函数实现多态
6.3.3 用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念 ...
- C++ 多态性和虚函数
2017-06-27 19:17:52 C++面向对象编程的一个重要的特性就是多态性,而多态性的实现需要依赖虚函数的帮助. 一.多态的作用: 隐藏实现细节,使得代码能够模块化: 接口重用,实现“一个接 ...
随机推荐
- ostream类重载的operator<<()函数
ostream类重载了operator<<()以识别不同的类型,如: int short long unsigned int unsigned short unsigned long f ...
- 【吐血推荐】简要分析unity3d中剪不断理还乱的yield
在学习unity3d的时候很容易看到下面这个例子: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yield ...
- 撸一撸腾讯的微信支付(C#)
一.前言 以往网上支付都是支付宝的天下,随着微信用户群的日益增多(其实,到现在我也不理解微信为嘛那么火,功能还没QQ强大,或许是公众号的原因?),先如今不上个微信支付你都不好意思说你系统支持在线支付. ...
- SharedPreferences实现记住密码功能
SharedPerferences 简单介绍 用于保存简单的键值对数据: 它将数据放在 /data/data/<package name>/shared_prefs目录下,用xml文件保存 ...
- 使用Java 8 Lambda表达式对Employee类进行操作
1,首先定义Employee类. package coffee.how.to.program.early.objects.chapter15; public class Employee { priv ...
- C++ Tempatet之模板模型
模板一共有三种类型: 1.第一种包含模型:包含模型是讲模板的定义和声明都放在头文件里(注:一般我们写的代码是将声明放在头文件里,实现放在cpp里,防止产生两份实现代码) 缺点:包含模型会增加代码的量. ...
- php中==与===区别
==是不判断二者是否是同一数据类型,而===是更为严格的比较,它不但要求二者值相等,而且还要求它们的数据类型也相同
- Somebody That I Used to Know
一.查看歌词 http://baike.baidu.com/view/7925491.htm 二.考量歌词 1.我告诉自己你就是我的挚爱 但你的陪伴却让我倍感孤单 但那就是爱 让我刻骨铭心难以忘怀 既 ...
- vector 的resize 和 reserve
首先声明,都是转载的,理解知识为主要目的. http://www.cnblogs.com/zahxz/archive/2013/02/20/2918711.html C++内置的数组支持容器的机制,但 ...
- safeseh+dep保护绕过
[文章作者] :h_one [漏洞程序名称]:mplayer.exe [漏洞类型] :缓冲区溢出 [保护方式] :safeseh+dep [操作平台] ...