在这个 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/