Experimenting with C++ inheritance diamonds and method resolution order
Sunday, July 13th, 2008It 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.