4

According what I read, virtual base class is used when you have a abstract base class that holds data, so the class wont be replicated, but, what is the problem with replicate the class, if you don't use virtual class?

And should abstract base class that holds data be avoided?

follows an example:

class Storable {
public:
  Storable(const string& s);
  virtual void read() = 0;
  virtual void write() = 0;
  virtual ~Storable();
protected:
  string file_name; // store in file named s
  Storable(const Storable&) = delete;
  Storable& operator=(const Storable&) = delete;
};

class Transmitter : public virtual Storable {
public:
  void write() override;
  // ...
};

class Receiver : public virtual Storable {
public:
  void write() override;
 // ...
};

class Radio : public Transmitter, public Receiver {
public:
  void write() override;
  // ...
};

This example was taken from the book The C + + Programming Language 4th Edition - Bjarne Stroustrup.

Alex
  • 3,301
  • 4
  • 29
  • 43
  • When I wrote duplicated class, it was not in this sense, I will not duplicate the code. – Alex Feb 16 '14 at 17:19
  • 2
    The problem is that you'd probably want the data to be identical for both instances, which becomes hard to maintain – StoryTeller - Unslander Monica Feb 16 '14 at 17:19
  • 1
    Have a look at diamond inheritance, e.g. [here](http://stackoverflow.com/questions/379053/diamond-inheritance-c). – Marc Claesen Feb 16 '14 at 17:22
  • The snarky-but-based-on-experience answer is _never_, because you shouldn't ever use virtual inheritance. If you're in a situation that virtual inheritance seems at all necessary then you should probably deeply rethink your class structure. If two of your base classes need a common set of functionality or data, use aggregation and dependency-injection instead. – Sean Middleditch Feb 17 '14 at 07:21

2 Answers2

5

To keep it short, if you wouldn't use virtual inheritance for Storable then Radio would inherit it twice, once from Transmitter and once from Receiver.

That means that Radio needs memory for 2 instances of Storable which is some memory overhead and you'd most likely want both to have identical data anyways (If you don't inherit it virtually you'd have to manually manage that).
Also when you call a base class function from Storable (or access a data member), which one do you want to call? The one from Storable that got inherited through Transmitter or the one from the Storable that got inherited through Receiver

Virtual inheritance takes care of that with only having a single instance of the Storable base class that all the inherited classes share.

For mor information on virtual base classes, there's a nice question here: In C++, what is a virtual base class?

Community
  • 1
  • 1
AliciaBytes
  • 7,300
  • 6
  • 36
  • 47
  • So, every time that I use a abstract base class, should I use virtual inheritance? – Alex Feb 16 '14 at 17:24
  • 1
    @Alex The problem occurs only when it would be inherited twice, like `T2` and `T3` inheriting from `T1` and `T4` inheriting from both `T2` and `T3`. – AliciaBytes Feb 16 '14 at 17:26
  • 1
    If you'd only inherit a single instance of `T1` then there'd be no need for a virtual base class. – AliciaBytes Feb 16 '14 at 17:26
  • 2
    @Alex: the design problem is that it's the *immediate* derived classes of the shared base that need to declare the inheritance virtual, but it's the *most derived* class that knows whether it will use multiple inheritance or not in a way that requires virtual inheritance to avoid duplication. So if you want your class `Transmitter` to support use in multiple inheritance in that way (or think you might) then yes, inherit virtually. But often in practice you're not in doubt, you don't want to support it :-) – Steve Jessop Feb 16 '14 at 18:11
2

Virtual base classes are used in virtual inheritance, are a way of preventing multiple "instances" of a given class appearing in an inheritance hierarchy when using multiple inheritances i.e. Just to avoid DIAMOND PROBLEM. To avoid this diamond problem we either use virtual base class or we use '::' i.e. scope resolution operator for clear understanding of what class's method or data we want to use. Please refer Diamond Problem

Community
  • 1
  • 1
Deva
  • 48
  • 6