Software Design & Engineering
Internet business development
mobile applications
Alan Partis
320 Ridgecreek Drive
Lexington, SC    29072
(803) 692-1101
alpartis@thundernet.com

 

Password Rules are Stupid
Common rules actually weaken security.

Best Practice ... Not!
This is one reason why "old" code can be touchy.

Wow! That was fast!
Making the right choices in your code can have huge payoffs in speed.

Ctors in Chains
Shrink your C++ code even more by chaining your constructors together.

Virtual Classes
Virtual base classes: what are they good for?!

Practice Makes Pretty Good
Become a master software engineer by practicing like a ninja warrior.

You Should Get Out More
Maintainability is the key to software success.

Why You Need Me
Seven reasons why I think you need me to work for you.

I Create Wealth
Or, why this is such a great business to be in.

Standards in Software
Software engineering standards are a necessary and good thing.

What is a Content Management System?
$10.5 billion will be spent on them this year (2003) alone, but what are they?

Top 10 Benefits of a Content Management System
So what good are they?

Do You Need a Blowfish?
What is a Blowfish? Does size matter? Is it right for me? Get your questions answered here.

Why Not Windows?
Don't just take my word for it ...

10 Attributes of a Professional Software Engineer
A truly professional software engineer stands out from the crowd. Here's what makes them different.

How to Score a Startup
Examine all these points of startup companies and see how they add up.

Virtual Classes

July, 2013

My apologies, dear readers, this post isn't about virtual schooling through on-line classes.  Instead, this is about the C++ keyword 'virtual' and its use in class inheritance.  Specifically, this is meant to help understand what the compiler does with multiple references to the same base class in a complex hierarchy of base and derived classes.

The informative and complete C++ reference web site (cppreference.com) provides a dry explanation for "Virtual base classes" that probably pretty much quotes the language specification:

For each distinct base class that is specified virtual, the most derived object contains only one base class subobject of that type, even if the class appears many times in the inheritance hierarchy (as long as it is inherited virtual every time).
I don't dispute that explanation (for obvious reasons), but I think I can paint a clear image of how to think about this.

When declaring a class in C++, we (the programmer) provide the details of what is contained within objects of that type -- we create a new complex data type.  What it contains is pretty clear; it contains the elements we just typed in. Now consider the slightly more complex case of class B being derived from class A.  By specifying that B derives from A, and then providing more details for B itself, we can say that B contains the elements of B and an A.

struct A { int a; }; // in addition to a character attribute, class B also // contains an A class i.e. an additional integer attribute struct B : A { char b; };

So, the objects of the derived class not only contain the member elements it declares, but also the member elements from the base class.

It would be incorrect to try to declare that B inherits from A twice:

struct B : A, A { char b; } but what if B inerited from 2 other classes, each of which derived from A themselves?  Would B then contain 2 copies of A?  The use of virtual derivation influences that answer.  Consider this class hierarchy: struct A { int a; }; // "middle layer" class inheriting from A struct X : A { int x; }; struct Y : A { int y; }; // now the derived class ... struct B : X, Y { char b; }; What does class B contain now?  It contains 2 integers 'a', an integer 'x' and an integer 'y' in addition to it's own character 'b'.  However, if the middle layer classes X and Y were to use virtual inheritance for base class A, then B would only contain 1 copy of A and its members.  Keep in mind that only if both middle layer classes used the virtual keyword would this consolidation take place.  If only X had virtual inheritance, then B would contain one 'virtual' copy of A and one 'non-virtual' copy of A.  If there were more middle layer classes then there would be one copy of A for all the 'virtual' bases, and one each for each of the 'non-virtual' base instances.

The takeaway from this is to remember to use virtual inheritance in related classes that each derive from a common base and where they, themselves, could be used as bases for some future classes.

The problem in the above hierarchy comes when an object instance of B is referred to as a pointer to X or Y.  In those cases, the 'a' integer attribute on B won't always be the same.

int main() { B *b = new B(); X *x = (X*)b; // b, x, and y are all pointing Y *y = (Y*)b; // to the same object now x->a = 2; // even though x and y both point to y->a = 3; // the b object, they a's might differ if (x->a == y->a) cout << "we used virtual inheritance" else cout << "we didn't use virtual inheritance" } The only other thing to note is that the order of execution for constructors is also influenced by the use of virtual inheritance: constructors for virtual base classes are executed before constructors on non-virtual base classes.

Now, as an exercise for the reader: in the above example, which 'a' is referenced by

b->a


"Thundernet" is a trademark of Thundernet Development Group, Inc.
a Florida corporation.
Copyright © Thundernet Development Group, Inc..
All rights reserved.