2010-04-06 3 views
6

Je suis nouveau en C++, alors gardez-moi. J'ai une classe générique appelée A. A a une classe imbriquée appelée B. A contient une méthode appelée getB(), qui est censée renvoyer une nouvelle instance de B. Cependant, je ne peux pas obtenir mon code à compiler. Voici à quoi il ressemble: #includePointeur de retour vers la classe interne imbriquée à partir de la classe externe générique

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

Lorsque je tente de compiler, je reçois l'erreur suivante:

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

Est-ce que quelqu'un sait ce que je fais mal?

Merci,

helixed

MISE À JOUR:

Merci pour tout le monde des réponses rapides. J'ai toujours du mal à faire fonctionner ça. Après avoir pris les suggestions énumérées ici, j'ai quelque chose comme ceci:

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 { 

}; 

Cependant, lorsque je tente d'utiliser du principal, je reçois une erreur. Voici ma méthode principale:

main.cpp

#include "A.h" 

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

Lorsque je tente de compiler, je reçois l'erreur suivante:

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

Merci encore pour les réponses rapides.

helixed

+3

Hmm, travaille sur Comeau .Mais même si cela compilé, cela aiderait-il? La définition de getB ne serait disponible que dans A.cpp. Comme il s'agit d'un modèle, il ne peut pas être appelé à partir d'une autre unité de traduction à moins que votre compilateur ne prenne en charge "export". –

+2

Réponse à l'édition: utilisez '->' pour l'accès des membres via un pointeur. –

+0

Oh, bonh, je me sens vraiment stupide maintenant. J'ai passé trop de temps en Java. Merci pour l'aide Steve. – LandonSchropp

Répondre

7

Le compilateur est pas assez intelligent pour comprendre que "B" est un type lorsque "A" est templated. Essayez d'utiliser le nom de fichier.

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

Et comme l'a mentionné Steve Jessop, gardez-le dans le fichier .h, pas dans le fichier .cc. – Stephen

+0

Cela a semblé résoudre le problème original. Cependant, j'ai encore un peu de mal, comme je l'ai posté ci-dessus. Merci pour l'aide. – LandonSchropp

+0

Utilisez: "A :: B * b = a-> getB();" Vous devez déréférencer le pointeur "a". – Stephen

2

Vous devez utiliser typename dans votre définition allusion au compilateur que B est un type.

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

Je vois ce que vous voulez dire. J'ai déplacé la définition dans le fichier A.h. Merci. – LandonSchropp

0

Réponse à la mise à jour:

Vous n'êtes pas obligé de new tout en C++, en fait, ce serait mieux si vous ne l'avez pas, depuis lors, vous devez explicitement delete la mémoire allouée ou utilisez des pointeurs intelligents.

Donc, voici votre code révisé:

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 vous souhaitez new la classe A<C>, vous devez utiliser le operator-> pour invoquer des méthodes:

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