2013-02-24 161 views
2

我有一个令人生畏的设计问题,我恳求一些建议。简而言之,我有两个基类AB,AImpl<T>BImpl<T>分别从AB继承。我需要的是从一个多态A*指针指向一个AImpl<T>对象检索(静态)BImpl<T>*,但没有A明确添加类似virtual B* getB()AImpl<T>因为BBImpl<T>已经覆盖它取决于A这将增加一个循环依赖。 AImpl<T>BImpl<T>专门针对原始类型,std :: string,T*等。专门的模板类循环依赖

任何好的建议?

编辑:前向声明在这里没有用,因为即使添加了f.d.在A.h中的B,并且将方法虚拟的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中明显包括A.h,反之亦然会导致循环依赖。请注意,这并不是我所拥有的,但显示了同样的问题。谢谢。

+0

向前声明'class B;'应该允许你在'A'中声明'virtual B * getB();'。一些示例代码会有所帮助。 – aschepler 2013-02-24 15:27:02

+1

同意@aschepler,这个位*“因为B和BImpl 已经依赖于A并且会添加循环依赖”*似乎表明您不知道前向声明的存在。如果情况并非如此,则需要向我们展示一些代码 – 2013-02-24 15:28:18

+0

程序员之间交流思想的工具是* code *。请使用它。 – 2013-02-24 15:34:56

回答

1

前向声明应该没问题,因为模板方法在使用之前不会被实例化。

尝试把这个在您的A.H的顶部:

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

那么你可以从内部B.H.包括A.H

+0

这就是现在(实际代码中)的实际情况,但不幸的是它不起作用。当询问getAImpl_of ()时,链接器抱怨“getBImpl_of ()”的未定义。我已经解决了重新设计整个系统。不管怎样,谢谢你。 – keebus 2013-02-24 19:04:59