私有虚函数的特点(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++面向对象编程的一个重要的特性就是多态性,而多态性的实现需要依赖虚函数的帮助. 一.多态的作用: 隐藏实现细节,使得代码能够模块化: 接口重用,实现“一个接 ...
随机推荐
- UIToolbar swift
// // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...
- UML详解
学习c++必不可少UML,UML从考虑系统的不同角度出发,定义了用例图.类图.对象图.状态图.活动图.序列图.协作图.构件图.部署图等9种图.这些图从不同的侧面对系统进行描述.系统模型将这些不同的侧面 ...
- Unity3D定制新建C#文件的头描述
1. 修改模板内容如下: MAC:Unity.app/Contents/Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt ...
- How to check if NSString begins with a certain character
How to check if NSString begins with a certain character How do you check if an NSString begins with ...
- Teamwork-Week2真对必应词典和有道词典的软件分析和用户需求调查(桌面版)
经调查,现在有道词典在该领域拥有很大程度的市场占有率,所以我们将有道词典与必应词典进行对比. 核心功能一:单词本 有道词典中的单词本都只能是由用户手动添加不会的单词,而必应词典中的单词 不仅可以被自己 ...
- 点亮led【转载】
http://linux-sunxi.org/Cubieboard/Programming/StatusLEDs Accessing the status LEDs The Cubieboard ha ...
- 我教女朋友学编程Html系列(6)—Html常用表单控件
做过网页的人都知道,html表单控件十分重要.基本上我们注册会员.登录用户,都需要填写用户名.密码,那些框框都是表单控件. 本来今天就想写一些常用的html表单控件,于是开始搜资料,找到了一个网页,作 ...
- android webview开启html5支持
最近做的一个小项目需要用到webview.虽然只是一个简单的网页,但是由于以前用的都只是显示本地文件,没有显示网页文件.现在需要显示网页文件,发现许多网站的webapp做的挺不错的,无论是显示还是用户 ...
- 【笔记】ASP.NET MVC Model元数据
问题1:什么叫Model元数据? Model元数据,是针对数据类型的一种描述信息.由于复杂类型(或者说类型嵌套的存在,比如CustomerModel中有一个属性为复杂类型Address)的存在,因此M ...
- HDU 5800 To My Girlfriend 背包
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5800 To My Girlfriend Time Limit: 2000/2000 MS (Java ...