7

How does the Virtual Differs in C++ and c#? basically i wanted to know is there any difference in the way Vtable is represented in C# and c++? Also is there any difference in the way the compiler creates the V Table in C# and c++?

Basically the interviewer wanted to know how does the compiler behaviour differrs for virtual functions in case of C# and c++.

I have answered the question mentioning there might be no difference in VTABLE expect that there is no Virtual Destructor in c#.

casperOne
  • 73,706
  • 19
  • 184
  • 253
uday
  • 211
  • 1
  • 3

4 Answers4

3

Who said anything about v-tables? Why are you assuming their existence?

The main difference (with relation to the syntax) is that in C++ the derived class doesn't have to know that the function is declared virtual in the ancestor class, and in C# you must use the override keyword.

littleadv
  • 20,100
  • 2
  • 36
  • 50
  • 2
    *"with relation to the syntax"?* Who asked about syntax? The OP's question was about "**the way the compiler creates the V Table in C# and c++**", not the language's syntax... – user541686 Aug 05 '11 at 03:32
  • 2
    @Mehrdad - no. That was the OP's **understanding**. The question is *How does the `Virtual` Differs in C++ and c#?*, then the OP goes and explains how **he** understood it, which is not what he was asked. – littleadv Aug 05 '11 at 03:34
3

You can call virtual functions in the constructor in C# (and get the expected behavior of calling through the virtual dispatch mechanism) but not in C++.

Though it is not recommended.

Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 3
    You can call `virtual` function from constructor. It's just that, it's always resolved to the static type of the caller. It's a well defined behavior. http://www2.research.att.com/~bs/bs_faq2.html#vcall – iammilind Aug 05 '11 at 03:47
  • 1
    @iammilind: And this is the same for C# is it!! The **point here** is that the two languages behave differently. In C++ you get the function in the last defined version (which if it is pure can be nothing thus UB) and this is always the wrong behavior (when you call a virtual function you expect virtual dispatch to the most derived version). In C# it correctly calls through the virtual dispatch mechanism. So please remove your incorrect down vote. – Martin York Aug 05 '11 at 04:34
  • 1
    I have learned to be pedantic from you only. I am removing my downvote. But still your `Though it is not recommended` line is not needed. Recommendation is a subjective term in this context. – iammilind Aug 05 '11 at 04:56
  • @iammilind: The C# compiler issue warnings if you touch virtuals in the constructor, so it is not entirely subjective. – Jörgen Sigvardsson Aug 05 '11 at 05:07
  • Right, and there is a warning in Microsoft's (static) [Code Analysis](http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx) (FxCop) for it as well. I would say that fully qualifies for "not recommended". – Christian.K Aug 05 '11 at 05:11
  • @iammillind: Bjarne even spell it out for you in his C++ FAQ. If D::f() depends on initialization in D::D(), then a virtual dispatch to D::f() from B::B() will be a very bad thing. – Jörgen Sigvardsson Aug 05 '11 at 05:15
  • @Jorgen, I am not talking about good/bad thing. But, whether it's legal or not. @Martin, you are wrong about pure `virtual` function thing. It's not UB, it's a [linker error](http://www.ideone.com/MZYfh). Ok, but let's not prolong the discussions and clutter the answer unnecessarily. – iammilind Aug 05 '11 at 05:25
  • @iammilind, nobody argued whether it's legal or not. It's still a bad thing to call something, when you can't be sure it will execute as *intended*. – Jörgen Sigvardsson Aug 05 '11 at 06:21
3

(1) In C# one can choose to override a virtual function from base class. Both base and derived methods can have same syntax, but derived method can participate in polymorphism only if it uses the keyword override before it. See this answer for more details.

In C++, if provided the same syntax method in derived class as base class virtual method; then it will be automatically be overridden. No choice.

(2) To be short, in C# we have abstract methods and in C++ pure virtual methods. Both may not be exactly same, but are equivalent (as pure virtual can have function body).

(3) In C++ we have choice to call virtual method without letting it participating in polymorphism. e.g. calling with an object, calling inside constructor.

(4) In C++, if the base virtual method is public and derived method is private than there is no difference for virtual mechanism, when the method is called with base handle (pointer or reference). Which means that their access specifier can be different.


Now coming to your 2nd question of how vtables are implemented. This is not really an objective question. Because in C++ itself different vendors implement the vtable in different ways (it's not in standard as pointed by @littleadve). So for interview sake you can answer that, vtables are platform dependent.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • What we're looking here is for the internal implementation; not really the syntax diff. – sarat Aug 05 '11 at 05:25
  • @sarat, OP has started with `How does the Virtual Differs in C++ and c#?`. Also I have tried to answer the main question in the second part. In first part I am not *just* discussing syntax diff; but the way compiler interprets their meaning. – iammilind Aug 05 '11 at 05:27
1

Martin's answer is correct, but deserves some further explanation.

Let's assume that vTables are the mechanism used for resolving virtual method invocations. That'll make the discussion easier.

In C++, each constructor in the inheritance hierarchy does the following:

  1. Call the base class constructor (if there is a base class).
  2. Set the instance's vTable pointer to the vTable for the current class.
  3. The stuff explicitly described in the constructor.

The vTable pointer changes over the course of the class initialization. As each base class constructor is invoked, the vTable "evolves" into it's most derived form.

In C#, the vTable pointer is set only once, before any of the constructor code is invoked. Only steps 1 and 3 described above happen for each class constructor in the hierarchy.

By making different design decisions here, C++ and C# essentially chose different, necessary evils.

In C++, there is the risk that a bad programmer may invoke a pure-virtual (a.k.a. "abstract") method. This happens when a base class constructor invokes a virtual method that is implemented in a more derived class. C++ also carries a risk that an overridden virtual method may be invoked.

The dangers in C#'s way of doing things are more subtle, but still potentially problematic. If a base class constructor invokes a virtual method, then that method is invoked before any of the initialization done in the constructor of the more derived class. This may violate the intended usage designed by the author of the more derived class.

Kennet Belenky
  • 2,755
  • 18
  • 20