D
Dave Rahardja
Since C++ is missing the "interface" concept present in Java, I've been using
the following pattern to simulate its behavior:
class Interface0
{
public:
virtual void fn0() = 0;
};
class Interface1
{
public:
virtual void fn1() = 0;
};
class Implementation0: public virtual Interface0, // note "public virtual"
public virtual Interface1
{
public:
virtual void fn0(); // implementation
virtual void fn1(); // implementation
/* ... */
};
I have consistently used public virtual inheritance whenever I'm implementing
(or extending) an interface, to ensure that there is only one instance of the
interface present in any class hierarchy.
Using virtual inheritance also allows me to create mixin classes. For example:
class DefaultInterface0Implementation : public virtual Interface0
{
public:
virtual void fn0(); // implementation
};
class Implementation1: public virtual Interface0,
public virtual Interface1,
private DefaultInterface0Implementation // mixin
{
public:
virtual void fn1(); // implementation
using DefaultInterface0Implementation::fn0(); // mixin behavior
/* ... */
};
This pattern has been successfully used in several projects.
Still, I can't help thinking that this pattern is overkill. Really, the only
time virtual inheritance is needed is when mixins are used (always at the
terminal implementation class definition). Virtual inheritance also costs time
(extra pointer indirection and construction sequence) and space (extra pointer
storage per object) at runtime. For objects that implement a handful of
interfaces, but maintain very little state, the added pointer storage can
represent 20-50% of the storage requirements.
There is also the side effect of not being able to downcast from a pointer to
an interface. However, I've found that with good OO design this is almost
never an issue (hint: serialization can be performed through a Serializable
interface).
Then why not select which interfaces to virtually inherit from at the terminal
implementation class definition? Because interfaces can extend other
interfaces:
class Interface2 { /* ... */ };
class Interface2A: public virtual Interface2 { /* ... */ };
class Interface2Mixin: public virtual Interface2 { /* implementation */ };
class Implementation: public virtual Interface2A, private Interface2Mixin
{ /* ... */ };
This pattern forces Interface2A to virtually inherit from Interface2.
Not using virtual inheritance consistently also causes trouble when _new_
mixin classes are developed. When a new mixin class is defined for future use,
the developer must search for all classes that derive from a particular
interface, and change their inheritance relationship to virtual. This causes a
lot of unneccessary code churning.
Although the rules I use are "always correct" for my purposes, they may not be
the most efficient for real life.
Does anyone have a better set of rules that I can consider using?
-dr
the following pattern to simulate its behavior:
class Interface0
{
public:
virtual void fn0() = 0;
};
class Interface1
{
public:
virtual void fn1() = 0;
};
class Implementation0: public virtual Interface0, // note "public virtual"
public virtual Interface1
{
public:
virtual void fn0(); // implementation
virtual void fn1(); // implementation
/* ... */
};
I have consistently used public virtual inheritance whenever I'm implementing
(or extending) an interface, to ensure that there is only one instance of the
interface present in any class hierarchy.
Using virtual inheritance also allows me to create mixin classes. For example:
class DefaultInterface0Implementation : public virtual Interface0
{
public:
virtual void fn0(); // implementation
};
class Implementation1: public virtual Interface0,
public virtual Interface1,
private DefaultInterface0Implementation // mixin
{
public:
virtual void fn1(); // implementation
using DefaultInterface0Implementation::fn0(); // mixin behavior
/* ... */
};
This pattern has been successfully used in several projects.
Still, I can't help thinking that this pattern is overkill. Really, the only
time virtual inheritance is needed is when mixins are used (always at the
terminal implementation class definition). Virtual inheritance also costs time
(extra pointer indirection and construction sequence) and space (extra pointer
storage per object) at runtime. For objects that implement a handful of
interfaces, but maintain very little state, the added pointer storage can
represent 20-50% of the storage requirements.
There is also the side effect of not being able to downcast from a pointer to
an interface. However, I've found that with good OO design this is almost
never an issue (hint: serialization can be performed through a Serializable
interface).
Then why not select which interfaces to virtually inherit from at the terminal
implementation class definition? Because interfaces can extend other
interfaces:
class Interface2 { /* ... */ };
class Interface2A: public virtual Interface2 { /* ... */ };
class Interface2Mixin: public virtual Interface2 { /* implementation */ };
class Implementation: public virtual Interface2A, private Interface2Mixin
{ /* ... */ };
This pattern forces Interface2A to virtually inherit from Interface2.
Not using virtual inheritance consistently also causes trouble when _new_
mixin classes are developed. When a new mixin class is defined for future use,
the developer must search for all classes that derive from a particular
interface, and change their inheritance relationship to virtual. This causes a
lot of unneccessary code churning.
Although the rules I use are "always correct" for my purposes, they may not be
the most efficient for real life.
Does anyone have a better set of rules that I can consider using?
-dr