2013-02-24 1 views
2

저는 어려운 디자인 문제가 있으며 몇 가지 조언을 구하고 있습니다. 진짜 짧게 말해서, 나는 두 개의 기본 클래스 AB을 가지고 있으며 AB을 각각 상속받은 AImpl<T>BImpl<T>을 상속합니다. 내가 필요한 것은 다형성 A* 포인터 켰던 AImpl<T> 객체에서 (정적) BImpl<T>*를 검색 할 수 있지만 명시 적으로 Avirtual B* getB() 같은 것을 추가하고 이미 AImpl<T> 때문에 BBImpl<T> 그것을 무시하지 않고 A에 의존하고 그 순환을 추가 의존. AImpl<T>BImpl<T>은 기본 유형 인 std :: string, T* 등의 특수 문자입니다.특수 템플릿 클래스 주기적 종속성

좋은 조언이 있습니까?

편집 : f. d.를 추가하기 때문에 forward 선언이 유용하지 않습니다. A.h에 B를 넣고 A에 메소드 B * getB()를 넣으면 AImpl이 템플릿 클래스이므로 메소드의 전체 정의가 필요합니다. getB()는 BImpl의 정적 인스턴스를 반환해야합니다.

다른 말로 문제를 설명하려면 다음과 같이하십시오. 사용자 cpp에서 나는 A.h를 포함하고 A 클래스를 사용합니다. AImpl가

const B* getB() const { 
    static BImpl<T> instance; 
    return &instance; 
} 

이 방법으로 정의 된 방법 getB()를 가지고 있다고 가정하면 순환 종속성 선도 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

+1

@aschepler와 동의합니다.이 비트는 "B와 BImpl 이 이미 A에 의존하고 순환 종속성을 추가하기 때문에"* 앞으로 선언이 있는지 알지 못하는 것 같습니다. 그게 아니라면, 우리에게 몇 가지 코드를 보여줄 필요가있다. –

+0

프로그래머 간의 아이디어 전달 수단은 * code *이다. 그것을 사용하십시오. –

답변

1

전달 방법 선언은 템플릿 메서드가 사용될 때까지 인스턴스화되지 않으므로 잘되어야합니다.

당신의 A.h의 상단이 퍼팅보십시오 :

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

는 다음 [B. 내에서 A.h를 포함 할 수 있습니다

+0

이것은 실제로 (실제 코드에서) 현재 사용되고 있지만 불행히도 작동하지 않습니다. getAImpl_of ()을 요청할 때 링커는 "getBImpl_of ()"의 정의를 불평합니다. 나는 전체 시스템을 재 설계했다. 어쨌든 고맙습니다. – keebus

관련 문제