Virtual Class Inheritance in C++
Java has notions of both class inheritance and interface inheritance, where interfaces are only sets of methods. To mimic this very useful behavior in C++ I often define classes with only a single method, such as
class Point;
struct PointSet
{
virtual bool contains (const Point & const) const = 0;
};
class Point
{
...
public:
inline bool in (const PointSet & point_set) const
{
return point_set.contains(*this);
}
...
};
so that when defining objects which “are”, among other things, sets of points, they can inherit as so:
class Environment
: public PointSet
{
...
public:
virtual bool contains (const Point & point) const { ... }
...
};
In complicated class hierarchies, it can be useful to aggregate such abstract interface classes, e.g.,
struct MetricSpace
: public PointSet
{ ... };
struct VectorSpace
: public PointSet
{ ... };
struct BanachSpace
: public MetricSpace,
public VectorSpace
{ ... };
But oops, BanachSpace is now a PointSet in two distinct ways, i.e. via VectorSpace::contains and via MetricSpace::contains. To avoid this so called “diamond problem”
PointSet PointSet PointSet
/ \ | |
VectorSpace MetricSpace vs VectorSpace MetricSpace
\ / \ /
BanachSpace BanachSpace
C++ designers invented virtual inheritance which allows a unique inheritance of each interface-like method, so that in
struct MetricSpace
: public virtual PointSet
{ ... };
struct VectorSpace
: public virutal PointSet
{ ... };
struct BanachSpace
: public virtual MetricSpace,
public virtual VectorSpace
{ ... };
References
C++ FAQ Lite,
Wikipedia
BanachSpace::contains is unique.
C++0x
Gcc 4.4 and later support nice C++0x features like hash tables via std::unordered_map and auto typed variables, as in
std::unordered_map<
std::pair,
std::vector<std::pair > > widgets = get_widgets();
for (auto i = widgets.begin(); i != widgets.end(); ++i) {
std::swap(i->second.first, i->second.second);
}
The new standard also allows variadic initializer lists with a small speed penalty.
My favorite features are: