#include <iostream> using namespace std; class Base { public: int i; Base() { i = 9999; fun(); } virtual void fun() { cout<<"Base.fun()"<<endl; } }; class Derived : public Base { public: int i; Derived() { i = -1; } virtual void fun() { cout<<"Derived.fun()"<<endl; } }; int main(int argc, char *argv[]) { Base *b = new Derived(); cout<<(b->i)<<endl; b->fun(); }
java 代码:
class Base { int i = 9999; public void fun() { System.out.println("Base.fun()"); } Base() { fun(); } } class Derived extends Base { int i = -1; Derived(){} public void fun() { System.out.println("Derived.fun()"); } } public class dev { public static void main(String argv[]) { Base b = new Derived(); System.out.println(b.i); b.fun(); } }
差异体现在第一行输出;
这行是在Derived的构造函数中输出的,Derived本身没有构造函数,它只调用父类的构造函数,即Base的Base(), 并执行其中的 fun() 函数;
对于C++代码,执行的是Base::fun();
对于Java代码,执行的是Derived::fun();
为什么呢,在C++中调用基类的fun时,此时子类还没有准备好,故执行的是基类的fun。
分析:区别原因在于编译器,及其运行原理
C++ 代码 经过编译后 Base构造函数中的代码为静态,其中调用的其他函数地址也已经在编译时 就已经确定, 故执行的是 Base::fun() 。(除了虚函数是动态联编其他的都是静态代码)
Java 代码,为动态联编, 各个函数在编译时已经形成虚拟机机器指令代码, 但是具体的函数调用却是动态的, 因为是派生类调用父类的构造函数,所以这里的 fun() 函数被认为是 派生类 derived 中的。
原文:http://www.cnblogs.com/devilmaycry812839668/p/6358477.html