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