C#VS C ++ - 类型,继承和虚函数表 [英] C# vs C++ - Types, inheritance and vtable

查看:218
本文介绍了C#VS C ++ - 类型,继承和虚函数表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解是什么原因导致C ++和C#之间的区别。

I'm having trouble understanding what causes this difference between C++ and C#.

首先,我们有在基类中包含虚函数的例子。

First we have an example in which the base class contains a virtual function.

class Base
{
protected:
    int super;
public:
    virtual int f() = 0;
};

class Derived : public Base
{
public:
    int extraA;
    int f(){ return 1; }
};

int main()
{
    Derived *d = new Derived();

    std::vector<Base*> v;
    v.push_back(d);

    for(int i=0; i < v.size() ;i++)
    {
            // Output "Derived"
            std::cout << typeid(*v[i]).name() << std::endl;
    }

    return 0;
}



这样做的输出,符合市场预期,派生。

The output of this is, as expected, "Derived".

如果我们去掉F(),这不再有效。输出为基础。例如:

If we remove f(), this no longer works. The output is "Base". Example:

class Base
{
protected:
    int super;
};

class Derived : public Base
{
public:
    int extraA;
};

int main()
{
    Derived *d = new Derived();

    std::vector<Base*> v;
    v.push_back(d);

    for(int i=0;i<v.size();i++)
    {
            // Output "Base"
            std::cout << typeid(*v[i]).name() << std::endl; 
    }

    return 0;
}



我对此的理解是,有一个虚函数使编译器添加一个的vptr的对象,它指向虚表。 V表包含正确的函数的地址调用(衍生:: F()) - (除了对象的类型信息)

My understanding of this is, that having a virtual function causes the compiler to add a vptr to the object, which points to the vtable. The vtable contains the address of the correct function to invoke (Derived::f()) - (As well as type information of the object?)

现在的有趣部分 - 用C#的比较。在这里,基地和派生基本上都是空类类似于第二个C ++的例子:

Now for the interesting part - Comparison with C#. Here, "Base" and "Derived" are basically empty classes similar to the 2nd C++ example :

public static void Main()
{
        Derived d = new Derived();
        IList<Base> v = new List<Base>();
        mList.Add(d);

        for (int i = 0; i < v.Count; i++)
        {
            // Output: "Derived"
            System.Console.WriteLine(v.ElementAt(i).GetType()); 
        }
}



我的问题是这样的:是我的C理解++部分正确的,如何做C#管理正确识别对象的类型时,C ++不?

My question is thus: Is my understanding of the C++ part correct, and how does C# manage to correctly identify the type of the object when C++ doesn't?

推荐答案

这是为你说:C ++实现运行时多态性和类型识别只,只要您的类有一个虚拟功能,这意味着(共同实现)一的vptr 添加到类(这是一致的的C ++你不付你不需要的东西的工作理念)。

It's as you say: C++ enables runtime polymorphism and type identification only whenever your class has a virtual function, which means that (in common implementations) a vptr is added to the class (this is coherent with the philosophy of C++ "you don't pay for what you don't need").

(除了作为对象的类型的信息?)

(As well as type information of the object?)

然而,这是共同的存储的指针一类的虚函数表的第一个时隙RTTI纪录 - 我会说,这是为什么标准要求RTTI仅如果类是多态的工作(虽然,像往常一样,这一切都是编译器相关的原因之一)。

Yet, it's common to store a pointer to the RTTI record in the first slot of the vtable of a class - and I'd say that this is one of the reasons why the standard requires RTTI to work only if the class is polymorphic (although, as usual, this all is compiler-dependent).

顺便说一句,RTTI是没有必要的虚拟调度才能正常工作,如果你调用虚函数所有的编译器所要做的就是做一个呼叫PTR 从虚函数表的正确插槽拍摄的指针;检查在的类层次结构时,将dynamic_cast ,并通过关于对象的类型,明确要求当的typeid 。

By the way, RTTI is not necessary for virtual dispatch to work correctly, if you call a virtual function all the compiler has to do is to do a call ptr with the pointer taken from the correct slot of the vtable; the RTTI record is used only when checking the class hierarchy in dynamic_cast and when asking explicitly about the type of an object via typeid.

在C#中,相反,每个类是默认多态性,具有关联反射的元数据,所以没有必要做任何事情,特别是使多态性/类型标识

In C#, instead, every class is polymorphic by default and has reflection metadata associated to it, so there's no need to do anything particular to enable polymorphism/type identification.

这篇关于C#VS C ++ - 类型,继承和虚函数表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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