2010-04-06 16 views
6

Soy nuevo en C++, así que tengan paciencia conmigo. Tengo una clase genérica llamada A. A tiene una clase anidada llamada B. A contiene un método llamado getB(), que se supone que devuelve una nueva instancia de B. Sin embargo, no puedo obtener mi código para compilar. Esto es lo que parece: # includeDevuelve el puntero a la clase interna anidada de la clase externa genérica

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

Cuando intento compilar esto, me sale el siguiente error:

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

¿Alguien sabe lo que estoy haciendo mal?

Gracias,

helixed

ACTUALIZACIÓN:

Gracias por las respuestas a todos rápida. Todavía estoy teniendo un pequeño problema para que esto funcione. Después de tomar los consejos que se muestran aquí, tengo algo como esto:

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 { 

}; 

Sin embargo, cuando trato de utilizar este de la principal, me sale un error. Aquí está mi principal método:

main.cpp

#include "A.h" 

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

Cuando intento compilar esto, me sale el siguiente error:

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

Gracias de nuevo por las respuestas rápidas.

helixed

+3

hmm, trabaja en Comeau .Pero incluso si esto se compilara, ¿sería útil? La definición de getB solo estaría disponible en A.cpp. Como se trata de una plantilla, no puede ser llamada desde ninguna otra unidad de traducción a menos que el compilador admita "exportar". –

+2

Respuesta a editar: use '->' para acceder a los miembros a través del puntero. –

+0

Oh, duh, me siento realmente estúpido ahora. He pasado demasiado tiempo en Java. Gracias por la ayuda Steve. – LandonSchropp

Respuesta

7

El compilador no es lo suficientemente inteligente como para darse cuenta de eso "B" es un tipo cuando se templated "A". Intenta usar typename.

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

Y como mencionó Steve Jessop, guárdelo en el archivo .h, no en el archivo .cc. – Stephen

+0

Esto pareció solucionar el problema original. Sin embargo, sigo teniendo un pequeño problema, como he publicado anteriormente. Gracias por la ayuda. – LandonSchropp

+0

Uso: "A :: B * b = a-> getB();" Debes eliminar la referencia del puntero "a". – Stephen

2

Es necesario utilizar typename en su definición a insinuar que el compilador que B es un tipo.

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

Veo tu punto. Moví la definición al archivo A.h. Gracias. – LandonSchropp

0

respuesta a la actualización:

que no es necesario que new todo en C++, de hecho, sería mejor si no lo hizo, desde entonces se tendría que explícitamente delete asigna la memoria o usa punteros inteligentes.

lo tanto, aquí está el código revisado:

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

Si desea new la clase A<C>, entonces es necesario utilizar el operator-> para invocar métodos:

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