I've been developing in C++ for some time when I was a student, but I never used virtual class or extern in C++ in any of the projects. I just recent read about these two, and was hoping if someone had a better understanding of their usage.
What is the purpose of virtual class? An example of where it could be used/implemented. I gloss over it a bit on IBM website and wrote a test program to see it in action, but when would it be good to use a virtual class?
The same goes for extern as well. I saw an example, and did a test for myself in C++, but what is the advantage of using extern instead of using a header file? And what is the advantage of a header file instead of extern?
Virtual classes are for when you encounter the dreaded diamond. For example:
struct Base { int x; };
struct D1 : Base {};
struct D2 : Base {};
struct Derived : D1, D2 {};
Here, Derived
actually has two Base
parts, and as a result two member variables called x
. It will compile, but you might experience some unexpected behaviour when manipulating a Derived
object through one of its base classes.
Derived derived;
D1& d1 = derived;
D2& d2 = derived;
d1.x = 1;
d2.x = 2;
cout << d1.x << d2.x << endl; // 12 !
Virtual inheritance solves this problem by making Derived
derive from Base
only once.
struct Base { int x; };
struct D1 : virtual Base {};
struct D2 : virtual Base {};
struct Derived : D1, D2 {};
Here, Derived
only has one Base
part, and one member variable called x
.
There are no virtual classes, but there's virtual inheritance, and virtually inherited base classes are often called virtual bases.
Example:
#include <iostream>
class IHello
{
public:
virtual char const* message() const = 0;
};
class HelloImpl
: public virtual IHello // Use virtual inheritance for interface
{
public:
virtual char const* message() const { return "Hello"; }
};
class Abstract
: public virtual IHello // Use virtual inheritance for interface
{
public:
void sayHello() const
{
using namespace std;
cout << "I'm saying... " << message() << "!" << endl;
}
};
class Concrete
: public Abstract
, public HelloImpl
{};
int main()
{
Concrete().sayHello();
}
Here virtual inheritance has the following effects:
There is only one base class sub-object of class IHello
.
The single sub-object of IHello
is initialized directly by the most derived class, here Concrete
.
The ordinary rules for ambiguous access are slightly amended, so that accessing message
is OK, and class HelloImpl
provides an implementation of message
via dominance, sort of like in Java and C# except that it's more general in C++.
If you replace the virtual inheritance with ordinary inheritance, then the above code won't even compile.
extern
versus header filesextern
and header files are orthogonal concepts.
extern
says that something has external linkage, and extern
is part of the language, a keyword.
A header file is a way of packaging code. Usually declarations are placed in header files, so that those declarations can be brought in via a #include
preprocessor directive. Header files are not part of the language (although the preprocessor is).
So, it does not make sense to "use extern
instead of a header file".
There is no particular relation, no task for which one could use one instead of the other.
Cheers & hth.,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With