2013-02-24 5 views
2

У меня сложная проблема дизайна, и я прошу совета. Короче говоря, у меня есть два базовых класса 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 и наоборот приводит к циклической зависимости. Обратите внимание, что это не совсем то, что у меня есть, но показывает ту же проблему. Спасибо.

+0

Форвард-декларирование 'class B;' должно позволить вам объявлять 'virtual B * getB();' в 'A'. Некоторый пример кода поможет. – aschepler

+1

Согласитесь с @aschepler, этот бит * ", потому что B и BImpl уже зависят от A, и это добавит циклическую зависимость" *, кажется, показывает, что вы не знаете о существовании форвардных объявлений. Если это не так, вам нужно показать нам код –

+0

. Транспортное средство для общения между программистами - это код *. Пожалуйста, используйте его. –

ответ

1

Вперед декларация должна быть прекрасной, поскольку методы шаблона не создаются, пока они не используются.

Попробуйте положить это в верхней части хиджры:

struct B; 
template <typename T> const B* getBImpl_of(); 

, то вы можете включить хиджры изнутри B.h.

+0

Это то, что на самом деле сейчас (в реальном коде), но, к сожалению, оно не работает. При запросе getAImpl_of () компоновщик жалуется на неопределенное определение «getBImpl_of ()». Я решил перепроектировать всю систему. В любом случае, спасибо. – keebus

Смежные вопросы