Есть простой и трудный путь.
Самый простой способ - ввести пустой виртуальный базовый класс. Каждый объект, унаследованный от такого класса, получает указатель на общую точку в «реальном» объекте, что вам и нужно. Указатель немного перегружен, но нет веток или чего-либо еще.
class V {};
class B1 : public virtual V {}; // sizeof(B1) = sizeof(void*)
class B2 : public virtual V {}; // sizeof(B2) = sizeof(void*)
class D : public B1, public B2 {}; // sizeof(D) = 2*sizeof(void*)
bool same( V const *l, V const *r ) { return l == r; }
Сложный путь - попытаться использовать шаблоны. Здесь уже есть несколько хаков ... при взломе с помощью шаблонов помните, что вы, по сути, заново изобретаете часть языка, просто с надеждой снизить накладные расходы путем управления информацией времени компиляции. Можем ли мы снизить накладные расходы виртуального базового класса и устранить этот указатель? Это зависит от того, сколько общности вам нужно. Если ваши базовые классы могут быть организованы несколькими различными способами в производном объекте, то, безусловно, есть информация, которую вы не можете получить во время компиляции.
Но если ваша иерархия наследования является перевернутым деревом (то есть вы строите большие объекты с помощью множества множественного наследования) или несколькими такими деревьями, вы можете просто продолжить и привести указатели к наиболее производному типу, как этот :
class C; // forward declare most derived type
class T { public: typedef C base_t; }; // base class "knows" most derived type
class B1: public T { int a; };
class B2: public T { int b; };
class D: public B1, public B2 { int c; };
// smart comparison function retrieves most-derived type
// and performs simple addition to make base pointers comparable
// (if that is not possible, it fails to compile)
template< class ta, class tb >
bool same( ta const *l, tb const *r ) {
return static_cast< typename ta::base_t const * >( l )
== static_cast< typename tb::base_t const * >( r );
}
Конечно, вы не хотите передавать указатели NULL на эту «оптимизированную» версию.