之前一直用C++编程,对虚函数还是一些较为肤浅的理解。可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题。

Java中的虚函数

以下是段别人的代码,输入结果竟是Base,这让一直以来用C/C++的我有些莫不着头脑,不是Java里对象是引用吗?C/C++中通过指向基类的指针或引用来指向派生类,那么对于虚函数来说通过基类指针使用的是指向的派生类。但在Java中没有keyword标明虚函数,此时就不是非常明确究竟调用的谁。

class base
{
private void print()
{
System.out.println("base");
}
public void doprint()
{
print();
}
} class derive extends base
{
private void print()
{
System.out.println("derive");
}
} class testVirtual
{
public static void main(String args[])
{
base b = new derive();
b.doprint();
} }

而以下这段Java输出的是derived,注意函数以及訪问权限的变化。

class base
{
public void print()
{
System.out.println("base");
}
public void doprint()
{
print();
}
} class derive extends base
{
public void print()
{
System.out.println("derive");
}
} class testVirtual
{
public static void main(String args[])
{
base b = new derive();
b.print();
}
}

大牛甲如是说:“java里的protected,public,包訪问级别的函数都是虚函数。”也有大牛乙如是说:“java里的都是虚函数。”我的解读是这二位大牛的话肯定都对,private级别的函数也能够说是虚函数,仅仅只是基类的引用无法直接訪问派生类的private级别的函数罢了,仅仅能訪问自己的。

于是能够断定以下这段就是输出derive了。没错,就是这样。

class base {
private void print() {
System.out.println("base");
} public void doprint() {
print();
}
} class derive extends base {
private void print() {
System.out.println("derive");
}
public void doprint() {
print();
}
} class testVirtual {
public static void main(String args[]) {
base b = new derive();
b.doprint();
}
}

C++中的虚函数

以下这段C++代码输出的是drived,通过基类的指针或引用指向派生类或基类,然后调用二者共同拥有都有的作为虚函数的函数,此时调用的是指针所指向的类(能够是基类也能够是派生类,关键看此时基类的指针或引用指向的是派生类还是基类)。注意仅仅有基类的指针或引用才干实现虚函数有关多态的问题,其它类型在C++中仅仅调用自己的函数。

#include<iostream>
using namespace std; class base
{
private:
virtual void print()
{
printf("base\n");
}
public:
void doprint()
{
print();
}
virtual ~base(){}
}; class derived : public base
{
virtual void print()
{
printf("derived\n");
}
}; int main(int argc, char* argv[])
{
derived d;
base& b = d;
b.doprint();
return 0;
}
//也是derived
#include<iostream>
using namespace std; class base
{
private:
virtual void print()
{
printf("base\n");
}
public:
void doprint()
{
print();
}
virtual ~base(){}
}; class derived : public base
{
private:
virtual void print()
{
printf("derived\n");
}
public:
void doprint()
{
print();
}
}; int main(int argc, char* argv[])
{
derived d;
base& b = d;
b.doprint();
return 0;
}
//输出的是base
#include<iostream>
using namespace std; class base
{
private:
virtual void print()
{
printf("base\n");
}
public:
void doprint()
{
print();
}
virtual ~base(){}
}; class derived : public base
{
private:
virtual void print()
{
printf("derived\n");
}
public:
void doprint()
{
print();
}
}; int main(int argc, char* argv[])
{
derived d;
base b = d;
b.doprint();
return 0;
}

以下这段输出的就是base了,由于不是虚函数,通过基类的指针或引用调用的就是基类的函数。

#include<iostream>
using namespace std; class base
{
public:
void print()
{
printf("base\n");
}
virtual ~base(){}
}; class derived : public base
{
public:
void print()
{
printf("derived\n");
}
}; int main(int argc, char* argv[])
{
derived d;
base& b = d;
b.print();
return 0;
}

以下C++代码输出的是derived,这就是同名覆盖原则,派生类覆盖积累的同名函数。

#include<iostream>
using namespace std; class base
{
public:
void print()
{
printf("base\n");
}
virtual ~base(){}
}; class derived : public base
{
public:
void print()
{
printf("derived\n");
}
}; int main(int argc, char* argv[])
{
derived d;
base& b = d;
d.print();
return 0;
}

总结对照

C++                     Java

虚函数     --------    普通函数

纯虚函数   --------    抽象函数

抽象类     --------    抽象类

虚基类     --------    接口     

      关于虚函数的实现机制,涉及虚函数表等,兴许博客补上。因为理论知识不足,难以上升到详细底层实现,望理解!

关于C++与Java中虚函数问题的读书笔记的更多相关文章

  1. C++虚函数【Java有虚函数吗?】

    1,简单介绍 定义在基类中的函数,子类必须对其进行覆写![必须对其进行覆写?!]——Java中的接口.Abstract方法中的抽象类也有这样的要求. C++中定义: virtual void deal ...

  2. C++中虚函数的作用浅析

    虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...

  3. C++中虚函数的作用是什么?它应该怎么用呢?(转)

    虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...

  4. C++中虚函数功能的实现机制

    要理解C++中虚函数是如何工作的,需要回答四个问题. 1.  什么是虚函数. 虚函数由于必须是在类中声明的函数,因此又称为虚方法.所有以virtual修饰符开始的成员函数都成为虚方法.此时注意是vir ...

  5. JAVA中字符串函数subString的用法小结

    本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...

  6. Java中的函数对象

    初次听说java中的函数对象可能,比较的陌生.可以类比着来理解一下,人们常说java中没有了指针,殊不知,java中的对象引用就是指针,有时候我们说一个对象往往指的就是这个对象的引用,也就是说基本上把 ...

  7. c++中虚函数

    虽然很难找到一本不讨论多态性的C++书籍或杂志,但是,大多数这类讨论使多态性和C++虚函数的使用看起来很难.我打算在这篇文章中通过从几个方面和结合一些例子使读者理解在C++中的虚函数实现技术.说明一点 ...

  8. C++中虚函数的作用和虚函数的工作原理

    1 C++中虚函数的作用和多态 虚函数: 实现类的多态性 关键字:虚函数:虚函数的作用:多态性:多态公有继承:动态联编 C++中的虚函数的作用主要是实现了多态的机制.基类定义虚函数,子类可以重写该函数 ...

  9. 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理

    二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...

随机推荐

  1. Linux 7 中Yum 配置 说明

    在之前的Blog中写了Linux Yum 的配置方法,参考: Linux 平台下 YUM 源配置 手册 http://www.cndba.cn/account/article/details/154 ...

  2. 关于Android Studio升级到2.0后和Gradle插件不兼容的问题

    今天升级AS到2.0后,用AS在真机上调试,发现报了如下错误: This version of Android Studio is incompatible with the Gradle Plugi ...

  3. POJ 1312 Numerically Speaking

    题意:a = 1, b = 2, ..., z = 26, aa = 27, ... 给字符串或者数字,输出对应的答案. 解法:类似26进制……但又不完全是……拿java大数模拟了一下…… 代码: i ...

  4. [Everyday Mathematics]20150131

    在 $\bbR^4$ 中定义如下有界区域 $\Omega$: $$\bex \Omega=\sed{(x,y,z,w)\in\bbR^4;\ |x|+|y|+\sqrt{z^2+w^2}\leq 1} ...

  5. golang语言部分保留字的举例

    golang和c的代码有很大不同的,一不小心就会误用. 1 /* go保留字: */ /* break default func interface select case defer go map ...

  6. 详解Asp.net MVC DropDownLists

    Asp.net MVC中的DropDownLists貌似会让一开始从Asp.net Forms转过来的程序员造成不少迷惑.这篇文章讲述了为了使用DropDownLists,你需要在Asp.Net MV ...

  7. DataGird导出EXCEL的几个方法

    DataGird导出EXCEL的几个方法(WebControl) using System;using System.Data;using System.Text;using System.Web;u ...

  8. 【跟我一起学Python吧】python学习摘要

    开始靖,怒推一篇文章:码农平时应该注意的办公室礼节 学习一门脚本语言是很有必要的,当我们在开发一些简单,快速程序时,脚本语言便有了用武之地,而且还很給力.根据python的介绍,python是一门很简 ...

  9. MFC DLL 资源模块句柄切换[转]

    以前写MFC的DLL的时候,总会在自动生成的代码框架里看到提示,需要在每一个输出的函数开始添加上 AFX_MANAGE_STATE(AfxGetStaticModuleState()).一直不明白这样 ...

  10. web.py实现jsonp

    浏览器端请求 $.getJSON("/currenttime?callback=?", function (json){ $("#time").html(jso ...