之前一直用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. HDU 5114 Collision

    Collision Time Limit: 15000/15000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Total ...

  2. MultiSet

    Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口.Guava中定义的新集合有: Multi ...

  3. IT版孔乙己(转)

    [不要做学究]回忆孔先生IT版 我关于本文评价:看到这篇文章很多人会生出这样的疑问“这明明是在诋毁钻研技术的人嘛?是不是在宣扬技术无用论?”. 初看这篇文章的时候我也是这样的想法,但是逐步才明白这篇文 ...

  4. 《C++ primer》--第12章

    习题12.7 什么是封装?为什么封装是有用的? 解答: 封装是一种将低层次的元素组合起来形成新的.高层次实体的技术.例如,函数是封装的一种形式:函数所执行的细节行为被封装在函数本身这个更大的实体中:类 ...

  5. HDU-4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632

    http://acm.hdu.edu.cn/showproblem.php?pid=4632 题意: 一个字符串,有多少个subsequence是回文串. 别人的题解: 用dp[i][j]表示这一段里 ...

  6. [selenium webdriver Java]元素定位——findElement/findElements

    策略 语法 语法 描述 By id driver.findElement(By.id()) driver.findElements(By.id()) 通过id属性定位元素 By name driver ...

  7. 常见设计模式解析和实现(C++)Prototype模式(原型模式)

    作用:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. UML结构图: 抽象基类: 1)  Prototype:虚拟基类,所有原型的基类,提供Clone接口函数 接口函数: 1)  P ...

  8. JSP中字符编码转换问题

    问题描述:一个input.jsp页面中的参数,传递到另外一个save.jsp页面上,然后存入到数据库中,如果input.jsp页面输入偶数中文没有问题,输入奇数则出现?,存入数据库的也是?. 问题源码 ...

  9. 使用k-means对3D网格模型进行分割

    使用k-means对3D网格模型进行分割 由于一些原因,最近在做网格分割的相关工作.网格分割的方法有很多,如Easy mesh cutting.K-means.谱分割.基于SDF的分割等.根据对分割要 ...

  10. Python 变量 对象 引用

    1.变量 变量第一次赋值时被创建,变量在使用前必须赋值 变量本身没有类型,变量类型为它引用的对象类型: 变量在使用时被替换成它引用的对象 2.对象 对象本身具有计数和类型,变量引用对象,当对象的引用变 ...