2010-04-06 6 views
6

Sono nuovo al C++, quindi abbi pazienza con me. Ho una classe generica chiamata A. A ha una classe nidificata chiamata B. A contiene un metodo chiamato getB(), che dovrebbe restituire una nuova istanza di B. Tuttavia, non riesco a compilare il mio codice. Ecco come si presenta: #includeRestituisce il puntatore alla classe interna annidata dalla classe esterna generica

Ah

template <class E> 
class A { 

public: 
    class B { 
    public: 
     int data; 
    }; 

    B * getB(); 
}; 

A.cpp

#include "A.h" 

template <class E> 
A<E>::B * A::getB() { 
    return new B(); 
} 

Quando provo a compilare questo, ottengo il seguente errore:

error: expected constructor, destructor, or type conversion before '*' token 

Qualcuno sa cosa sto sbagliando?

Grazie,

helixed

UPDATE:

Grazie per le risposte veloci tutti. Sto ancora avendo qualche problema a farlo funzionare. Dopo aver preso i suggerimenti elencati qui, ho qualcosa di simile:

A.h

template <class E> 
class A { 

public: 
    class B { 
    public: 
     int data; 
    }; 

    B * getB(); 
}; 

template <class E> 
typename A<E>::B * A<E>::getB() { 
    return new B(); 
} 

class C { 

}; 

Tuttavia, quando provo ad usare questo dal principale, ottengo un errore. Ecco il mio metodo principale:

main.cpp

#include "A.h" 

int main(int argc, char *argv[]) 
{ 
    A<C> *a = new A<C>(); 
    A<C>::B *b = a.getB(); 
} 

Quando provo a compilare questo, ottengo il seguente errore:

error: request for member 'getB' in 'a', which is of non-class type 'A<C>*' 

Grazie ancora per le risposte rapide.

helixed

+3

Hmm, funziona su Comeau .Ma anche se fosse compilato, sarebbe d'aiuto? La definizione per getB sarebbe disponibile solo in A.cpp. Dato che si tratta di un modello, non è possibile chiamarlo da un'altra unità di traduzione a meno che il compilatore non supporti "esportazione". –

+2

Risposta a modifica: usare '->' per l'accesso membro tramite puntatore. –

+0

Oh, duh, mi sento davvero stupido ora. Ho passato troppo tempo in Java. Grazie per l'aiuto Steve. – LandonSchropp

risposta

7

Il compilatore non è abbastanza intelligente per capire che "B" è un tipo quando "A" è templato. Prova ad usare typename.

template <class E> 
typename A<E>::B * A<E>::getB() { 
    return new B(); 
} 
+0

E come menzionato da Steve Jessop, tienilo nel file .h, non nel file .cc. – Stephen

+0

Questo sembrava risolvere il problema originale. Tuttavia, ho ancora un po 'di problemi, come ho postato sopra. Grazie per l'aiuto. – LandonSchropp

+0

Utilizzare: "A :: B * b = a-> getB();" Devi dereferenziare il puntatore "a". – Stephen

2

è necessario utilizzare typename nella definizione accennare al compilatore che B è un tipo.

template <class E> 
typename A<E>::B * A::getB() { 
    return new B; 
} 
+0

Vedo il tuo punto. Ho spostato la definizione nel file A.h. Grazie. – LandonSchropp

0

risposta all'aggiornamento:

Non hai bisogno di new tutto in C++, in realtà, sarebbe meglio se non l'avete fatto, da allora si dovrà esplicitamente delete la memoria allocata o usare puntatori intelligenti.

Così, qui è il tuo codice rivisto:

template <class E> 
class A { 

public: 
    class B { 
    public: 
     int data; 
    }; 

    B getB(); // Object, not pointer 
}; 

template <class E> 
typename A<E>::B A<E>::getB() { 
    return B(); 
} 

#include "A.h" 

int main(int argc, char *argv[]) 
{ 
    A<C> a = A<C>(); 
    A<C>::B b = a.getB(); 
} 

Se si desidera new classe A<C>, allora avete bisogno di utilizzare il operator-> per richiamare i metodi:

A<C>::B b = a->getB();