July 13, 2008

Experimenting with C++ inheritance diamonds and method resolution order

It seems like g++ uses the order indicated in the class' derivation list over the order indicated in the base specifier list, as in the below example:

#include <iostream>

using namespace std;

class Animal {
public:
    Animal() {
        cout < < "Animal!" << endl;
    }
};

class Man : public virtual Animal {
public:
    Man(string exclamation) {
        cout << "Man " << exclamation << "!" << endl;
    }
};

class Bear : public virtual Animal {
public:
    Bear(string exclamation) {
        cout << "Bear " << exclamation << "!" << endl;
    }
};

class Pig : public virtual Animal {
public:
    Pig(string exclamation) {
        cout << "Pig " << exclamation << "!" << endl;
    }
};

class ManBearPig : public Man, public Bear, public Pig {
public:
    ManBearPig(string exclamation)
        : Pig(exclamation), Bear(exclamation), Man(exclamation)
    {
        cout << "ManBearPig " << exclamation << "!" << endl;
    }
};

int main() {
    ManBearPig mbp("away");
    return 0;
}
cdleary@gamma:~/projects/sandbox/sandbox_cpp$ g++ diamond.cpp && ./a.out
Animal!
Man away!
Bear away!
Pig away!
ManBearPig away!

Note that this experiment is a pretty (very) weak basis for the conclusion — it could be using lexicographic order, order based on the day of month, or any number of other unlikely heuristics :) A lot more experimentation is necessary before getting a discernible pattern, but I just felt like messing around.

Edit (07/27/08): Using correct "base specifier list" terminology instead of my made-up "class initializer list" terminology.