bobobobo
bobobobo

Reputation: 67254

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

I have a class, say A

template <typename T> class A
{
} ;

and a class derived from A<T>, (retaining type genericity)

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

A situation has arisen where i need to instantiate a B<T> inside a method declared in A<T>. Uh oh.

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

What should I do and how do I work around this?

Upvotes: 1

Views: 76

Answers (3)

Jon
Jon

Reputation: 437424

You can forward-declare the class template A before inheriting from it -- just be sure to follow the definition of class B with the definition of the class A template in the same header:

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>();
    }
};

Upvotes: 1

bobobobo
bobobobo

Reputation: 67254

Another way to do this is write a global function that each of the template classes declare 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>
}

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

You need to break the cyclic dependency between the two classes. Trivial in this case: just define your go() function out of line:

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>() ;
}

I prefer out of line definitions, even when inlining functions, anyway because it avoids cluttering the interface with unnecessary detail. I also prefer to not have cyclic dependencies (certainly not between base and derived) but it can't always be avoided.

Upvotes: 2

Related Questions