2012-11-28 90 views
1

我有一个类的方法派生类,说A我做了什么?需要实例化一个模板类

template <typename T> class A 
{ 
} ; 

A<T>派生的类,(保留型通用性)

template <typename T> class B : public A<T> 
{ 
} ; 

情况出现我需要在A<T>中声明的方法中实例化B<T>。呃哦。

template <typename T> class A 
{ 
    void go() 
    { 
     B<T> * newB = new B<T>() ; // oh boy, not working.. 
    } 
} ; 

我应该怎么做,我该如何解决这个问题?

+0

哇,什么头微调! –

回答

2

你需要打破两个类之间的循环依赖关系。平凡在这种情况下:刚才定义go()功能脱节:

template <typename T> class A 
{ 
public: 
    void go(); 
} ; 

template <typename T> class B : public A<T> 
{ 
} ; 

template <typename T> 
void A<T>::go() 
{ 
    B<T> * newB = new B<T>() ; 
} 

我喜欢脱节的定义,即使内联函数时,无论如何,因为它避免了混乱与不必要的细节的接口。我也更喜欢没有循环依赖(当然不在基础和派生之间),但它不总是可以避免的。

+0

每当我尝试这个而不指定'T'的具体类型(如模板专业化)时,我倾向于获得链接器错误 – bobobobo

+1

那么你似乎有一种倾向,以某种形式做错了......只要定义是在需要隐式实例化(即它在一个头文件中)并正确写入的位置,它可以工作。 –

+0

哦,好的。所以'template void A :: go()'仍然在标题中,它只是在'template class B:public A '之后。被我耍到了。 – bobobobo

1

你可以从它继承之前前瞻性声明类模板A - 只是一定要遵循B类的定义,在同一标题的类A模板的定义:

template <typename T> class A; 

template <typename T> class B : public A<T> {}; 

template <typename T> class A 
{ 
    void go() 
    { 
     B<T> * newB = new B<T>(); 
    } 
}; 
+1

你所做的陈述是错误的:你**不能**从一个前向声明的类继承* class *。然而,只要基类是在实例化点定义的,你就可以从一个前向声明的类模板继承一个*类模板*。原因是无论如何基类实际上可能是专业化的。 –

+0

@DietmarKühl:谢谢你的评论。班级模板确实是我想到的,但术语却没有了。 – Jon

0

另一种方式来做到这一点的是写一个全局函数,每个templatedeclare friend

void go(A<T> *a) 
{ 
    // Can now make a B<T> 
    B<T> *b = new B<T>() ; 
    // access b's and a's privates if this function 
    // is friend to A<T> and B<T> 
} 
相关问题