我做了什么?需要在模板化类的方法中实例化派生类

What have I done? Need to instantiate derived class in method of a templated class

本文关键字:方法 派生 实例化 什么      更新时间:2023-10-16

我有一个类,比如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..
    }
} ;

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

您需要打破两个类之间的循环依赖关系。在这种情况下微不足道:只需在行外定义您的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>() ;
}

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

在从类模板继承之前,你可以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>();
    }
};

另一种方法是编写一个全局函数,每个template类都声明 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>
}