Java与C++中的函数重写

Kam*_*mel 15 c++ java polymorphism overriding

Java和C++中有两个相似的定义,但行为完全不同.

Java版本:

class base{
    public void func1(){
        func2();
    }
    public void func2(){
        System.out.println(" I am in base:func2() \n");
    }

}

class derived extends base{
    public void func1(){
        super.func1();
    }
    public void func2(){
        System.out.println(" I am in derived:func2() \n");
    }
};
public class Test
{
    public static void main(String[] args){
        derived d = new derived();
        d.func1();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

I am in derived:func2()
Run Code Online (Sandbox Code Playgroud)

C++版本:

#include <stdio.h>

class base
{
    public:
        void func1(){
            func2();
        }
        void func2(){
            printf(" I am in base:func2() \n");
        }
};

class derived : public base
{
    public:
        void func1(){
            base::func1();
        }
        void func2(){
            printf(" I am in derived:func2() \n");
        }
};

int main()
{
    derived *d = new derived();
    d->func1();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

I am in base:func2()
Run Code Online (Sandbox Code Playgroud)

我不知道为什么他们有不同的行为.

即使我知道Java具有自动多态行为.

Java输出很难理解.

在我看来,根据static scope,基类函数func1()应该只能调用基类函数func2(),因为它根本不知道派生类.否则调用行为属于dynamic scope.也许在C++中,func2()基类是绑定static,但在Java中它是绑定的dynamic吗?

成员字段是静态范围的.


类型推断部分令人困惑.我以为this是转换成了base类型base::func1().在C++中,base::func2()不是多态,所以base::func1()调用它.而在Java中,base::func2()是多态,因此devried::func2()被称为.

如何func2()推断类绑定?或者fun2()应该调用哪个以及如何确定.

背后发生了base::func1()什么?是否有投这里this(从derivebase)?如果不是,怎么this能在base课堂上达到这个功能?

        void func1(){
            func2();
        }
Run Code Online (Sandbox Code Playgroud)

关于coderanch的有用讨论.

aio*_*obe 21

在Java中,所有可以覆盖的方法都是自动虚拟的.它没有选择加入机制(virtual关键字),因为它在C++中(并且也没有办法选择退出).

Java的行为就像你声明的base::func2一样

virtual void func2(){
    printf(" I am in base:func2() \n");
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您的程序将打印出来"I am in derived:func2()".

如何func2()推断类绑定?应该调用
哪个fun2()以及如何确定.

对于非虚方法(没有virtual修饰符的C++方法),它是确定调用哪个方法的静态类型.变量的静态类型由变量声明确定,并不依赖于代码的执行方式.

对于虚方法(带有virtual修饰符和所有 Java方法的C++方法),运行时类型决定了调用哪个方法.运行时类型是运行时中实际对象的类型.

示例:如果有

Fruit f = new Banana();
Run Code Online (Sandbox Code Playgroud)

静态类型fFruit和运行时类型fBanana.

如果你这样做f.someNonVirtualMethod(),将使用静态类型Fruit::someNonVirtualMethod并将被调用.如果您这样做f.someVirtualMethod(),将使用运行时类型Banana::someVirtualMethod并将被调用.

编译器如何实现此目标的基础实现基本上取决于实现,但通常使用vtable.详情请参阅


如果不是,怎么this能在base课堂上达到这个功能?

void func1(){
    func2();
}
Run Code Online (Sandbox Code Playgroud)

如果你想知道为什么func2()在这里呼吁basefunc2是因为

A)你在其范围内base意味着静态类型thisbase,和

B)func2base不是虚拟的,所以它是静态类型决定调用哪个实现.