473,480 Members | 3,106 Online
Bytes | Software Development & Data Engineering Community
Create 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.ValueType
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.ValueType. 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.Object. 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.WriteLine(p1.GetType()); // "Point"
// p1 does NOT get boxed to call CompareTo.
// p2 does NOT get boxed because CompareTo(Point) is called.
Console.WriteLine(p1.CompareTo(p2)); // "-1"
// p1 DOES get boxed, and the reference is placed in c.
IComparable c = p1;
Console.WriteLine(c.GetType()); // "Point"
// p1 does NOT get boxed to call CompareTo.
// Since CompareTo is not being passed a Point variable,
// CompareTo(Object) is called which requires a reference to
// a boxed Point.
// c does NOT get boxed because it already refers to a boxed Point.
Console.WriteLine(p1.CompareTo(c)); // "0"
// c does NOT get boxed because it already refers to a boxed Point.
// p2 does get boxed because CompareTo(Object) is called.
Console.WriteLine(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.WriteLine(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 1785

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

Similar topics

4
4409
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...
5
2907
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...
3
2168
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...
8
2822
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...
8
1608
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...
10
2242
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:...
13
3207
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...
4
2182
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...
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
7055
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7061
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,...
0
7030
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...
0
5367
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,...
1
4799
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4503
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...
0
3015
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...
0
1313
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
210
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...

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.