Передать на D и
в обеих ветвях:
D& d = (rand() %2 == 0 ? static_cast<D&>(c.getD1()) : static_cast<D&>(c.getD2()));
Кстати, вам действительно не нужно использовать условный оператор,
D* dptr; if(rand() %2 == 0) dptr = &c.getD1(); else dptr = &c.getD2();
D& d = *dptr;
тоже подойдет.
Или вы можете изменить возвращаемые типы функций на базовый класс.