Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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?

like image 492
shinozaki Avatar asked Dec 29 '22 05:12

shinozaki


2 Answers

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.

like image 87
Peter Alexander Avatar answered Jan 11 '23 05:01

Peter Alexander


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, 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 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.,

like image 20
Cheers and hth. - Alf Avatar answered Jan 11 '23 07:01

Cheers and hth. - Alf