从调用父类构造函数的重载方法 [英] Calling an overridden method from a parent class ctor

查看:125
本文介绍了从调用父类构造函数的重载方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从一个父类的构造函数调用一个重写的方法,发现不同语言不同的行为。

I tried calling an overridden method from a constructor of a parent class and noticed different behavior across languages.

C ++ - 回声 A.foo()

C++ - echoes A.foo()

class A{

public: 

    A(){foo();}

    virtual void foo(){cout<<"A.foo()";}
};

class B : public A{

public:

    B(){}

    void foo(){cout<<"B.foo()";}
};

int main(){

    B *b = new B(); 
}



的Java - < STRONG>回声 B.foo()

Java - echoes B.foo()

class A{

    public A(){foo();}

    public void foo(){System.out.println("A.foo()");}
}

class B extends A{  

    public void foo(){System.out.println("B.foo()");}
}

class Demo{

    public static void main(String args[]){
        B b = new B();
    }
}



C# - 回声 B.foo()

C# - echoes B.foo()

class A{

    public A(){foo();}

    public virtual void foo(){Console.WriteLine("A.foo()");}
}

class B : A{    

    public override void foo(){Console.WriteLine("B.foo()");}
}


class MainClass
{
    public static void Main (string[] args)
    {
        B b = new B();              
    }
}



我意识到,在C ++对象是从顶级创建大多数家长下去层次,所以当构造函数调用覆盖的方法,B甚至不存在,所以它调用A'版本的方法。但是,我不知道为什么我收到(从C ++)

I realize that in C++ objects are created from top-most parent going down the hierarchy, so when the constructor calls the overridden method, B does not even exist, so it calls the A' version of the method. However, I am not sure why I am getting different behavior in Java and C# (from C++)

推荐答案

在C ++中,你正确地指出,该对象的类型为 A 直到 A 构造完成。该对象实际上改变其施工期​​间类型。这就是为什么 vtable中的 A 是使用,所以 A :: foo的()被调用,而不是 b :: foo的()

In C++, as you correctly noted, the object is of type A until the A constructor is finished. The object actually changes type during its construction. This is why the vtable of the A class is used, so A::foo() gets called instead of B::foo().

在Java和最底层派生型的C#中,虚函数表(或同等机构)在整个使用,即使是在施工的基类。因此,在这些语言中, B.foo()被调用。

In Java and C#, the vtable (or equivalent mechanism) of the most-derived type is used throughout, even during construction of the base classes. So in these languages, B.foo() gets called.

请注意,它一般不建议调用从构造一个虚拟的方法。如果你不小心,虚拟方法可能假定对象被完全构造,尽管事实并非如此。在Java中,其中的每个方法是含蓄虚拟的,你别无选择。

Note that it is generally not recommended to call a virtual method from the constructor. If you're not very careful, the virtual method might assume that the object is fully constructed, even though that is not the case. In Java, where every method is implicitly virtual, you have no choice.

这篇关于从调用父类构造函数的重载方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆