java - Java 和 C++ 中的动态方法调度

标签 java c++ dynamic

在这个 C++ 程序中,

#include<iostream>
using namespace std;

class Base
{

    public:

    Base()
    {
        cout<<"\n\nBase ctr";
        fun();
    }  

    virtual void fun()
    {
        cout<<"\n\nBase's fun()";
    }
};

class Derived : public Base
{
    public:

    Derived()
    {
        cout<<"\n\nDerived ctr";
        fun();
    }

    virtual void fun()
    {
        cout<<"\n\nDerived's fun()";
    }
};
    int main()
    {
        Derived obj;
        return 0;
    }

当使用派生类对象从基类的构造函数调用虚函数时,会调用基类的 fun(),

输出::
基本控制

基地的乐趣()

衍生点击率

Derived 的 fun()

解释原因here 但是

在这个java程序中,

class Base
{
    Base()
    {
        System.out.println( "\n\nBase ctr" );
        fun();
    }
    void fun()
    {
        System.out.println( "\n\nBase's fun()" );
    }
}

class Derived extends Base
{
    int a=1;

    Derived()
    {
        System.out.println( "\n\nDerived ctr a = "+a );

        a=8;
        fun();
    }

    void fun()
    {
       System.out.println( "\n\nDerived's fun() a = "+a );
    }

    public static void main(String args[])
    {
       Derived obj = new Derived();
    }
}

输出是::
基本控制

Derived 的 fun() a = 0

派生点击率 a = 1

Derived 的 fun() a = 8

在这里,派生类 fun() 被调用,所以 constraint适用于c++程序,不适用于JAVA程序。为什么?

最佳答案

这两种语言采用不同的方法进行动态调度。在 C++ 中,它只会分派(dispatch)给一个完全构造的对象。这是通过在构造期间更改对象的类型来处理的,因为层次结构构造函数的不同级别开始执行。另一方面,Java 在启动最基本的构造函数之前就将对象视为派生程度最高的类型。

Java 方法的问题在于它实际上可能在尚未构建的对象上执行代码。考虑派生类型有一个初始化为 X 的字段,并且它在方法中被访问/更新。在基础对象上调用该方法将在构造函数初始化它之前访问该成员。

无论如何,您应该避免在任何一种语言的对象的构造函数或析构函数中调用虚函数。


示例:

public class Base {
   public final int x;
   public Base() { 
      x = foo();
   }
   int foo() { return 1; }
}
public class Derived extends Base {
   public final int y;
   public Derived() {
      y = 2;
   }
   int foo() { return y; }
}
Derived d = new Derived();
assert( d.x == d.y );                      // Can this ever fail?

在这段代码中,我们有 2 个 final int,代码看起来很简单,可以进行推理。 assert 会失败吗?

关于java - Java 和 C++ 中的动态方法调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10800802/

相关文章:

java - 端口转发 Devstack 尝试连接到本地 IP 而不是 Swift 中端口转发的 IP 地址

java - Jconsole 基于密码的身份验证

c++ - 获取CUDA错误 “declaration is incompatible with previous ” variable_name“

c++ - 删除动态分配的二维数组时发生错误?

java - 如何为 SOAP 请求生成 UsernameToken?

Java/JVM(热点): Is there a way to save JIT performance gains at compile time?

c++ - 如何在linux/c++中控制主音量?

c++ - Cocos2dx 动画(不使用过时的方法)

jquery - 如何动态查找下一个li标签

c# - 如何使用动态 settings.Blah 而不是 AppSettings ["blah"]?