Working around the Diamond Problem in C++

The “Diamond Problem” occurs in object-oriented code when multiple inheritance is employed, in situations where there are two subclasses sharing a parent, and another class inheriting both of those subclasses. This creates a virtual diamond shape of inheritance, hence the name.

struct Grandparent{ int x; };
struct A : public Grandparent{};
struct B : public Grandparent{};
struct Child : public A, public B{};

The problem is in that common ancestor. In C++, each inheritance occurs independently, meaning there are two instances of the grandparent class. Accessing them isn’t intuitive, though, as a simple member access attempt would be ambiguous and likely cause a compile error:

Child c;
c.x; //which instance's x attribute?

Accessing each individual x attribute isn’t straightforward, but it can be done. By framing the Child object using references, we can treat the object as either an A or a B, giving us named access to the juicy integers within:

((A&)child).x = 1;
((B&)child).x = 2;
std::cout << "\"A\".x = " << ((A&)child).x << std::endl;
std::cout << "\"B\".x = " << ((B&)child).x << std::endl;

Of course, depending on the design you had in mind, two separate Grandparent objects in memory may not be the desired layout. To have a single object, structs A and B should be declared like so:

struct A : public virtual Grandparent{};
struct B : public virtual Grandparent{};

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: