Usage of virtual class and extern in C++
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 t开发者_如何转开发est 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
.
Virtual inheritance
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, hereConcrete
.The ordinary rules for ambiguous access are slightly amended, so that accessing
message
is OK, and classHelloImpl
provides an implementation ofmessage
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 files
extern
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.,
Virtual Class is used to remove the diamond shape problem. To better understand this problem consider the scenario
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
class B:public A
{
public:
int j;
};
class C:public A
{
public:
int k;
};
class D:public B,public C
{
public:
int l;
};
A
/ \
/ \
B C
\ /
\ /
D
Here B and C inherits A. So the properties (variable and function) exists in both of the class. Again when D inherits Both C and B, then the properties of B and C alongside the properties of A that exists in both the class copied in the class D. So there arise a contradiction. this problem is diamond shape problem. This can be removed my making the base class A as virtual class which prevent this duplication. Thanks
精彩评论