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(从derive到base)?如果不是,怎么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)
静态类型f是Fruit和运行时类型f是Banana.
如果你这样做f.someNonVirtualMethod(),将使用静态类型Fruit::someNonVirtualMethod并将被调用.如果您这样做f.someVirtualMethod(),将使用运行时类型Banana::someVirtualMethod并将被调用.
编译器如何实现此目标的基础实现基本上取决于实现,但通常使用vtable.详情请参阅
如果不是,怎么
this能在base课堂上达到这个功能?Run Code Online (Sandbox Code Playgroud)void func1(){ func2(); }
如果你想知道为什么func2()在这里呼吁base的func2是因为
A)你在其范围内base意味着静态类型this是base,和
B)func2在base是不是虚拟的,所以它是静态类型决定调用哪个实现.
| 归档时间: |
|
| 查看次数: |
2457 次 |
| 最近记录: |