Это значит: объект класса B должен иметь (или не иметь) «товарища» класса C. Иметь не во владении, а по ссылке. А лучше не класса C, а его подмножества, реализованного как интерфейс (я его назвал IC). На A вообще чхаем — его задача собрать B и C в нужном виде, и всё.
Смотрите шаблон проектирования Dependency Injection.
class IC { // interface
public:
virtual int getC() = 0;
virtual ~IC() = default;
};
class C : public IC {
public:
int getC() final { return 42; }
};
class B {
public:
IC* buddy() const { return fBuddy; }
void setBuddy(IC* aBuddy) { fBuddy = aBuddy; }
void someJob() const { if (fBuddy) std::cout << fBuddy->getC() << std::endl; }
private:
IC* fBuddy = nullptr;
};
class A {
public:
A() { b.setBuddy(&c); }
private:
C c;
B b;
}
Специально для тех, кто на Си++: в таком виде A неперемещаем из-за указателя c.fBuddy. Есть много способов исправить это — например, подправить конструктор копирования и операцию «присвоить» класса A.