Во-первых, как указано в комментарии, все эти функции-члены являются закрытыми, поэтому ни одна из них не может вызывать другие. Предполагая, что это опечатка, и все они на самом деле помечены как publi c (или каждый класс является другом всех других, что определенно не очень хорошая идея), это можно сделать довольно простым способом.
В D::set()
вы хотите позвонить C::set()
. Это легко. Просто сделайте это:
void D::set(string s) {
C::set(s);
}
И теперь вы хотите, чтобы C::set()
позвонил B::get()
. Вы не можете сделать это напрямую, потому что C
не знает о B
. Но, поскольку get()
является виртуальной функцией, вы можете вызывать ее и полагаться на виртуальную диспетчеризацию для получения единственного переопределителя, а именно B::get()
. То есть:
void C::set(string s) {
std::string res = get();
}
Это работает, потому что этот конкретный объект C
фактически является частью объекта D
, а каждый объект D
имеет подобъект B
, который переопределяет A::get()
. В простом старом C
объекте этот вызов get()
вызовет A::get()
.
Просто чтобы прояснить: это очень запутанная иерархия классов, поэтому не смущайтесь из-за потери. С другой стороны, потеря может означать, что это слишком сложно, и здесь есть проблема с дизайном.