У меня сложная проблема дизайна, и я прошу совета. Короче говоря, у меня есть два базовых класса A
и B
и AImpl<T>
и BImpl<T>
, наследующие от A
и B
соответственно. Что мне нужно, чтобы получить (статический) BImpl<T>*
из AImpl<T>
объекта, на который указывает полиморфного A*
указатель, но без явного добавления что-то вроде virtual B* getB()
в A
и опрокинув его в AImpl<T>
, потому что B
и BImpl<T>
уже зависит от A
и что бы добавить циклический зависимость. Оба AImpl<T>
и BImpl<T>
предназначены для примитивных типов, std :: string, T*
и т. Д.Специализированные классы шаблонов циклическая зависимость
Полезный совет?
Редактировать: форвардная декларация здесь не полезна, потому что даже добавление f.d. из B в A.h и ставя метод виртуального B * getB() в A, являясь AImpl классом шаблона, для этого потребуется полное определение метода. getB() должен возвращать статический экземпляр BImpl.
Чтобы объяснить проблему в других терминах, это то, что происходит: в пользовательском cpp я включаю A.h и использую классы A. Предположим, что AImpl имеет метод getB() определяется как
const B* getB() const {
static BImpl<T> instance;
return &instance;
}
этот метод требует полного включения B.h, что приводит к циклической зависимости.
Редактировать 2, полный код примера Я попытаюсь привести его в простой пример кода, надеясь лучше объяснить мою озабоченность.
// File A.h
struct A
{
virtual ~A();
void const A* getChild() const { /* ... */}
virtual const B* getB() const = 0;
};
template <typename T>
struct AImpl : public A
{
const B* getB() const
{
return getBImpl_of<T>();
}
};
// Specializations of AImpl<T>
template<typename T>
const A* getAImpl_of()
{
static AImpl<T> instance;
return &instance;
}
// File B.h
struct B
{
template<typename T>
static void work()
{
getBImpl_of<T>()->doWork();
}
virtual ~B();
protected:
virtual void doWork() = 0;
};
template <typename T>
struct BImpl : public B
{
protected:
void doWork()
{
const A* pA = getAImpl_of<T>();
// ... do something with pA ...
// Here is the key point:
const A* pChild = pA->getChild();
pChild->getB()->doWork();
}
};
template<typename T>
const B* getBImpl_of()
{
static BImpl<T> instance;
return &instance;
}
Это то, что я хотел бы сделать, но, очевидно, в том числе хиджры в B.h и наоборот приводит к циклической зависимости. Обратите внимание, что это не совсем то, что у меня есть, но показывает ту же проблему. Спасибо.
Форвард-декларирование 'class B;' должно позволить вам объявлять 'virtual B * getB();' в 'A'. Некоторый пример кода поможет. – aschepler
Согласитесь с @aschepler, этот бит * ", потому что B и BImpl уже зависят от A, и это добавит циклическую зависимость" *, кажется, показывает, что вы не знаете о существовании форвардных объявлений. Если это не так, вам нужно показать нам код –
. Транспортное средство для общения между программистами - это код *. Пожалуйста, используйте его. –