473,545 Members | 1,863 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Need help to understand virtual functions

153 New Member
I am reading a book which says

Even though unboxed value types don't have a type object pointer, you can still call virtual
methods (such as Equals, GetHashCode, or ToString) inherited or overridden by the type. The
reason is because the CLR can just call these methods nonvirtually and System.ValueTyp e
overrides all of these virtual methods and expects the value in the this argument to refer to an
unboxed value type instance. Remember, a value type is implicitly sealed, and therefore, a
value type cannot be used as the base class of another type. This means that it's impossible for
a value type's virtual method to be overridden by a derived type. This also means that the CLR
can call a value type's virtual methods nonvirtually.



However, calling a nonvirtual inherited method (such as GetType or MemberwiseClone )
requires the value type to be boxed because these methods are defined by System.Object,
so the methods expect the this argument to be a pointer that refers to an object on the heap.
In addition, casting an unboxed instance of a value type to one of the type's interfaces requires
the instance to be boxed, because interface variables must always contain a reference to an
object on the heap. The following code
demonstrates:

Expand|Select|Wrap|Line Numbers
  1. using System; 
  2. internal struct Point : IComparable { 
  3. private Int32 m_x, m_y; 
  4. // Constructor to easily initialize the fields 
  5. public Point(Int32 x, Int32 y) { 
  6. m_x = x; 
  7. m_y = y; 
  8. }
  9. // Override ToString method inherited from System.ValueType 
  10. public override String ToString() { 
  11. // Return the point as a string 
  12. return String.Format("({0}, {1})", m_x, m_y); 
  13. }
  14.  
  15. // Implementation of type-safe CompareTo method 
  16. public Int32 CompareTo(Point other) { 
  17. // Use the Pythagorean Theorem to calculate 
  18. // which point is farther from the origin (0, 0) 
  19. return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y) 
  20. - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y
  21. }
  22. // Implementation of IComparable's CompareTo method 
  23. public Int32 CompareTo(Object o) { 
  24. if (GetType() != o.GetType()) { 
  25. throw new ArgumentException("o is not a Point"); 
  26. }
  27. // Call type-safe CompareTo method 
  28. return CompareTo((Point) o); 
  29. }
  30. }
  31.  
  32. public static class Program { 
  33. public static void Main() { 
  34. // Create two Point instances on the stack. 
  35. Point p1 = new Point(10, 10); 
  36. Point p2 = new Point(20, 20); 
  37. // p1 does NOT get boxed to call ToString (a virtual method). 
  38. Console.WriteLine(p1.ToString()); // "(10, 10)" 
  39.  
  40. // p1 does NOT get boxed to call CompareTo. 
  41. // p2 does NOT get boxed because CompareTo(Point) is called. 
  42. Console.WriteLine(p1.CompareTo(p2)); // "-1" 
  43. // p1 DOES get boxed, and the reference is placed in c. 
  44. IComparable c = p1; 
  45. Console.WriteLine(c.GetType()); // "Point" 
  46. // p1 does NOT get boxed to call CompareTo. 
  47. // Since CompareTo is not being passed a Point variable, 
  48. // CompareTo(Object) is called which requires a reference to 
  49. // a boxed Point. 
  50. // c does NOT get boxed because it already refers to a boxed Point. 
  51. Console.WriteLine(p1.CompareTo(c)); // "0" 
  52. // c does NOT get boxed because it already refers to a boxed Point. 
  53. // p2 does get boxed because CompareTo(Object) is called. 
  54. Console.WriteLine(c.CompareTo(p2)); // "-1" 
  55.  
  56. // c is unboxed, and fields are copied into p2. 
  57. p2 = (Point) c; 
  58. // Proves that the fields got copied into p2. 
  59. console.WriteLine(p2.ToString()); // "(10, 10)" 
  60. }

This code demonstrates several scenarios related to boxing and unboxing:
• Calling ToString In the call to ToString, p1 doesn't have to be boxed. At first, you'd
think that p1 would have to be boxed because ToString is a virtual method that is inher-
ited from the base type, System.ValueTyp e. Normally, to call a virtual method, the CLR
needs to determine the object's type in order to locate the type's method table. Since p1
is an unboxed value type, there's no type object pointer. However, the C# compiler sees
that Point overrides the ToString method, and it emits code that calls ToString directly
(nonvirtually) without having to do any boxing. The compiler knows that polymor-
phism can't come into play here since Point is a value type, and no type can derive from
it to provide another implementation of this virtual method.
• Calling GetType In the call to the nonvirtual GetType method, p1 does have to be
boxed. The reason is that the Point type inheritsGetType fromSystem.Obje ct. So to call
GetType, the CLR must use a pointer to a type object, which can be obtained only by
boxing p1.
• Calling CompareTo (first time) In the first call to CompareTo, p1 doesn't have to be boxed
because Point implements the CompareTo method, and the compiler can just call it
directly. Note that aPoint variable (p2) is being passed toCompareTo, and therefore, the
compiler calls the overload of CompareTo that accepts a Point parameter. This means
that p2 will be passed by value to CompareTo and no boxing is necessary.
// p DOES get boxed to call GetType (a non-virtual method).
Console.WriteLi ne(p1.GetType() ); // "Point"
// p1 does NOT get boxed to call CompareTo.
// p2 does NOT get boxed because CompareTo(Point ) is called.
Console.WriteLi ne(p1.CompareTo (p2)); // "-1"
// p1 DOES get boxed, and the reference is placed in c.
IComparable c = p1;
Console.WriteLi ne(c.GetType()) ; // "Point"
// p1 does NOT get boxed to call CompareTo.
// Since CompareTo is not being passed a Point variable,
// CompareTo(Objec t) is called which requires a reference to
// a boxed Point.
// c does NOT get boxed because it already refers to a boxed Point.
Console.WriteLi ne(p1.CompareTo (c)); // "0"
// c does NOT get boxed because it already refers to a boxed Point.
// p2 does get boxed because CompareTo(Objec t) is called.
Console.WriteLi ne(c.CompareTo( p2)); // "-1"
// c is unboxed, and fields are copied into p2.
p2 = (Point) c;
// Proves that the fields got copied into p2.
console.WriteLi ne(p2.ToString( )); // "(10, 10)"
}
}Chapter 5: Primitive, Reference, and Value Types 141
• Casting to IComparable When casting p1 to a variable (c) that is of an interface type,
p1 must be boxed because interfaces are reference types by definition. So p1 is boxed,
and the pointer to this boxed object is stored in the variable c. The following call to
GetType proves that c does refer to a boxed Point on the heap.
• Calling CompareTo (second time) In the second call to CompareTo, p1 doesn't have to be
boxed becausePoint implements theCompareTo method, and the compiler can just call
it directly. Note that an IComparable variable (c) is being passed-toCompareTo, and
therefore, the compiler calls the overload of CompareTo that accepts anObject para-
meter. This means that the argument passed must be a pointer that refers to an object on
the heap. Fortunately, c does refer to a boxed Point, and therefore, that memory address
in c can be passed to CompareTo, and no additional boxing is necessary.
• Calling CompareTo (third time) In the third call to CompareTo, c already refers to a boxed
Point object on the heap. Since c is of the IComparable interface type, you can call only
the interface's CompareTo method that requires an Object parameter. This means that
the argument passed must be a pointer that refers to an object on the heap. So p2 is
boxed, and the pointer to this boxed object is passed to CompareTo.
• Casting to Point When casting c to a Point, the object on the heap referred to by c is
unboxed, and its fields are copied from the heap to p2, an instance of the Point type
residing on the stack.

PLEASE HELP ME UNDERSTAND IT.

How can a virtual method be called non-virtually ?
Mar 23 '09 #1
0 1792

Sign in to post your reply or Sign up for a free account.

Similar topics

4
4416
by: vijay | last post by:
I have a doubt with size of classed with virtual functions I have declared A,A1,A2 ,B , C, D some classes with no varaibles but a vitual function each, The size of A is as expected 4 bytes with one vtbl ptr BUt when I derive the class B from class A (both have 1 virtual function each ) the size remains still as 4 bytes . class A ...
5
2916
by: Ryan Faulkner | last post by:
Hi, Im having a few problems with virtual functions (Im using the Visual C++ environment by the way). I have a base class with three virtual functions and a derived class with a single new virtual function plus redefinitions of the three inherited virtual functions. Following is a simplified code fragment to illustrate my code and my...
3
2172
by: CoolPint | last post by:
I read that the return type has to be exactly same for a virtual function to be overriden. While testing something, I discovered something I cannot understand. I cannot understand why the code below compiles. I see that it won't compile if I have "virtual char & vtest() { }" in Base class and have "virtual const char & vtest() { }" in...
8
2828
by: JustSomeGuy | last post by:
I need to write an new class derived from the list class. This class stores data in the list to the disk if an object that is added to the list is over 1K in size. What methods of the std stl list class must Ioverride in order for this to work?
8
1611
by: Gunnar G | last post by:
Hi. I'm sorry for this somewhat off-topic message, but since this is the best place to find clever C++ programmers with a lot of wisdom. What I need is suggestions for a C++ project that takes about a week or two to complete, and where you really see the advantage with OO (inheritance, polymorphism etc.). Most ideas I have are easily done...
10
2250
by: mark | last post by:
I have this class: class Selections { OSStatus Init(); protected: CFMutableSetRef selectionObjects; static void CFASelectionsApplier(const void* value, void* ctx); OSType ready; public: Selections();
13
3221
by: Fao | last post by:
Hello, I am having some problems with inheritance. The compiler does not not return any error messages, but when I execute the program, it only allows me to enter the number, but nothing else happend. I think the problem may be in my input function or in the main function. If anyone out there can help me it woul be greatly appreciated. ...
4
2195
by: robinsand | last post by:
My apologies to those of you who are more advanced Visual C++ .NET programmers, but I am working on a project for an MBA course that is condensed into an eight-week schedule, and I need help getting a program up and running with proper files and documentation to be handed in for a grade (on Microsoft Visual Studio .NET 2003). I am being...
4
278
by: Neo | last post by:
I have the following code structure- class A { public: virtual void foo_a()=0; }; class B { public: virtual void foo_b()=0; };
0
7420
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7680
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7446
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7778
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6003
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4966
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3476
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
1033
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
731
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.