C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 25:
[25.8] What is the "dreaded diamond"?

The "dreaded diamond" refers to a class structure in which a particular class appears more than once in a class's inheritance hierarchy. For example,

class Base {
  int data_;

class Der1 : public Base { ... };

class Der2 : public Base { ... };

class Join : public Der1, public Der2 {
  void method()
     data_ = 1;   bad: this is ambiguous; see below

int main()
  Join* j = new Join();
  Base* b = j;    bad: this is ambiguous; see below
Forgive the ASCII-art, but the inheritance hierarchy looks something like this:
                         /  \
                        /    \
                       /      \
                    Der1      Der2
                       \      /
                        \    /
                         \  /
Before we explain why the dreaded diamond is dreaded, it is important to note that C++ provides techniques to deal with each of the "dreads." In other words, this structure is often called the dreaded diamond, but it really isn't dreaded; it's more just something to be aware of.

The key is to realize that Base is inherited twice, which means any data members declared in Base, such as data_ above, will appear twice within a Join object. This can create ambiguities: which data_ did you want to change? For the same reason the conversion from Join* to Base*, or from Join& to Base&, is ambiguous: which Base class subobject did you want?

C++ lets you resolve the ambiguities. For example, instead of saying data_ = 1 you could say Der2::data_ = 1, or you could convert from Join* to a Der1* and then to a Base*. However please, Please, PLEASE think before you do that. That is almost always not the best solution. The best solution is typically to tell the C++ compiler that only one Base subobject should appear within a Join object, and that is described next.