You are here:

C++/virtual functions

Advertisement


Question
sir

the basic concept of virtual functions in c++ is that it will see to it that it wll not allow duplicate values in a hybrid inheritance.

suppose i have a grandparent class inherited by parent 1 and parent 2, the two parents are being inherited by a child class.

suppose i declare constructors for the two parent classes and the grandparent class and i am invoking a display function through the child which value will be displayed


Answer
I think you may be confusing virtual functions with virtual inheritance. I also think that by values you might mean class instance data members.

Virtual functions have little to do with values - other than the may take values as parameters and return a value, and of course that they use them in their logic. They are the C++ mechanism for supporting the object oriented technique called polymorphism. They allow sub-classes to override the behaviour of base (super) classes with their own, and when such a sub-class object has an overridden virtual function called through a pointer or reference to the base class type it is the sub-class's implementation of the virtual function that gets called.

Virtual inheritance however prevents having two or more instances of common base class sub-objects in a single object. Without virtual inheritance the situation you describe would mean that object of the child type would have a parent1 and parent2 base sub-object _both_ of which would have a base class sub-object of the grandparent type, thus:

   Grandparent sub-object    Grandparent sub-object
         ^          ^
     Parent1 sub-object        Parent2 sub-object
         ^          ^
         Child object


(Note: like code the object representation diagrams are best viewed using a mono-spaced font such as Courier. This is because they are very, very simple - sorry but drawings do not form part of AllExpert answers - we have text and that is it!). In C++ it would look like so:

   class Grandparent { ... };
   class Parent1 : public Grandparent { ... };
   class Parent2 : public Grandparent { ... };
   class Child : public Parent1, public Parent2 { ... };

However if the Grandparent class were a virtual base class of both Parent1 and Parent2 then there will only be one Grandparent sub-object in hierarchies that have Parent1 and Parent2 base classes, thus:

         Grandparent sub-object
         ^(virtual)       ^ (virtual)
     Parent1 sub-object        Parent2 sub-object
         ^          ^
         Child object

In C++ it would look like so:

   class Grandparent { ... };
   class Parent1 : public virtual Grandparent { ... };
   class Parent2 : public virtual Grandparent { ... };
   class Child : public Parent1, public Parent2 { ... };

Notice the use of the virtual keyword when deriving Parent1 and Parent2 from Grandparent.

Now assuming the display function you are talking about is declared in the Grandparent base class (which I assume it must be for your query to make sense, however I might have the wrong end of the stick here - thus it is always best to be very precise in such descriptions and *say* how this display function is declared and *what* defines it - is it virtual? If so does the child class override it, or the parent types? Without such information my answer may not be as useful as I may not get the full context of your scenario as it is in your head and not in the question text!).

In the case of a non-virtual display function declared and defined for the Grandfather class _without_ virtual inheritance trying to call it from an instance of a child object results in an ambiguity, and the compiler issues an error:

   Child ch;

   // Parent1::Grandparent::display() or Parent2::Grandparent::display() ?
   ch.display(); // error! Ambiguous

We can resolve this by qualifying the call to specify which one we want thus:

   ch.Parent1::display(); // OK: call Parent1::Grandparent::display()
   ch.Parent2::display(); // OK: call Parent2::Grandparent::display()

However the following is _still_ ambiguous:

   ch.Grandparent::display(); // error! Ambiguous - which Grandparent?

[
At least it should be so according to both my understanding, my reading of the not-so-obvious wording in the standard and Dr. Bjarne Stroustrup in The C++ Programming Language Special Edition, section 15.2.3 Replicated Base Classes, in which I have just double checked);

MSVC 8.0 I just tried it on accepts it and always refers to the Grandparent::display from the first base that has Grandparent as base. Parent1 at the moment but if we changed the order of inheritance for Child thus:

   class Child : public Parent2, public Parent1 { ... };

then VC 8.0 will call display for the Grandparent part of Parent2 instead. Not a good situation which is why it _should_ be ambiguous.
]

Now what if display were the same except that it was a virtual function?

If it is only defined (implemented) for the Grandparent class then the situation is the same as with the non-virtual case. Also if Parent1 and/or Parent2 override the display function then the situation is similar except that if there is an override then

   ch.Parent1::display();
   ch.Parent2::display();

will call the override rather than the base, Grandparent implementation.

If the Child class overrides the display function then this can be called from child objects. Doing so could allow for say both parent base implementations to be called:

   void Child::display()
   {
       Parent1::display();
       Parent2::display();

    // Child specific stuff...

   }

Now let us look as the situation when using the virtual base classes for Parent1 and Parent2. In this case there is only one Grandparent sub object of a child object.

Starting again with the case where display is not virtual and is declared and defined only for the Grandparent class. Because there is only one Grandparent sub-object in a child object then calling display form a child object is no longer ambiguous:

   ch.display(); // OK - only one Grandparent sub-object

Now if display were virtual then it is only ambiguous if _both_ Parent1 and Parent2 override display. This is because if only one of them overrides display that one override hides the definition in the one and only Grandparent sub-object instance. If both override the display function then child inherits both definitions and the compiler complains; the solution as before would be to override display in the Child class.

For your information the sections on virtual base classes comes under derived classes in the ISO C++ standard in chapter 10. The name lookup and ambiguity rules are in section 10.2, and virtual functions in 10.3.

Hope this helps. Usually I have a second compiler at hand to double check code as I do not always believe Visual C++ has it correct (come to that g++ does not get it correct 100% of the time but is probably closer most of the time things differ between my compilers and/or the standard!) but I am in the middle of a system upgrade and only have the Windows based Visual C++ compiler installed at the moment - my Linux based g++ compiler is not available again yet.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.