gpt4 book ai didi

java - Java 与 C++ 中的函数覆盖

转载 作者:IT老高 更新时间:2023-10-28 22:26:45 27 4
gpt4 key购买 nike

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();
}
}

输出:

I am in derived:func2()

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;
}

输出:

I am in base:func2()

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

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

Java 输出个人很难理解。

在我看来,根据static scope,基类函数func1()应该只能调用基类函数func2 (),因为它对派生类一无所知。否则调用行为属于动态范围。也许在 C++ 中,基类中的 func2() 是绑定(bind) static,但在 Java 中是绑定(bind) dynamic

成员字段是静态作用域的。


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

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

base::func1() 背后发生了什么? this(从 derivebase)是否有任何类型转换?如果不是,this 是如何访问 base 类中的函数的?

        void func1(){
func2();
}

Useful discussion在 coderanch 上。

最佳答案

在 Java 中,所有可以被覆盖的方法都是自动的 virtual .它没有像 C++ 中那样的选择加入机制(virtual 关键字)(也没有办法选择退出)。

Java 的行为就像您将 base::func2 声明为

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

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

How the func2() class binding being inferred?
Which fun2() should be called and how it is determined.

对于非虚拟方法(没有 virtual 修饰符的 C++ 方法),静态类型决定了调用哪个方法。变量的静态类型由变量声明决定,与代码如何执行无关。

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

示例:如果您有

Fruit f = new Banana();

f的静态类型是Fruitf的运行时类型是Banana

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

编译器如何实现这一点的底层实现基本上取决于实现,但通常使用 vtable。详情引用


If no, how this is able to reach to the function in base class?

void func1(){
func2();
}

如果你想知道为什么这里的 func2() 调用 basefunc2 那是因为

A) 你在 base 的范围内,这意味着 this 的静态类型是 base,并且

B) base 中的 func2not 虚拟的,因此决定调用哪个实现的是静态类型。

关于java - Java 与 C++ 中的函数覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30883519/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com