2010-04-06 15 views
6

Jestem nowicjuszem w C++, więc weź ze mną. Mam klasę generyczną o nazwie A. A ma zagnieżdżoną klasę o nazwie B. A zawiera metodę o nazwie getB(), która ma zwrócić nową instancję B. Jednak nie mogę skompilować mojego kodu. Oto jak to wygląda: #includeZwróć wskaźnik do zagnieżdżonej klasy wewnętrznej z ogólnej klasy zewnętrznej

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

Kiedy próbuję skompilować ten, pojawia się następujący błąd:

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

Czy ktoś wie, co robię źle?

Dzięki,

helixed

UPDATE:

Dzięki za szybkie odpowiedzi każdego. Nadal mam trochę problemów z działaniem. Po zrobieniu sugestie wymienione tutaj, mam coś takiego:

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 { 

}; 

Jednak, gdy staram się korzystać z tego głównego, otrzymuję komunikat o błędzie. Tu jest mój główny sposób:

main.cpp

#include "A.h" 

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

Kiedy próbuję skompilować ten, pojawia się następujący błąd: znowu

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

Dzięki za szybkie odpowiedzi.

helixed

+3

hmm, działa na Comeau .Ale nawet gdyby to skompilowało, pomogłoby? Definicja getB byłaby dostępna tylko w A.cpp. Ponieważ jest to szablon, nie można go było wywołać z innej jednostki tłumaczeniowej, chyba że twój kompilator obsługuje "eksport". –

+2

Odpowiedź na edycję: użyj '->', aby uzyskać dostęp do członka za pomocą wskaźnika. –

+0

Och, duh, teraz czuję się naprawdę głupio. Spędziłem za dużo czasu w Javie. Dzięki za pomoc Steve. – LandonSchropp

Odpowiedz

7

Kompilator nie jest wystarczająco inteligentny, aby zrozumieć, że „B” jest rodzajem gdy „A” na matrycy. Spróbuj użyć nazwy pliku.

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

I jak wspomniał Steve Jessop, trzymaj go w pliku .h, a nie w pliku .cc. – Stephen

+0

To wydawało się naprawić oryginalny problem. Jednak nadal mam trochę problemów, jak napisałem powyżej. Dzięki za pomoc. – LandonSchropp

+0

Użycie: "A :: B * b = a-> getB();" Musisz wyłuskać wskaźnik "a". – Stephen

2

Musisz użyć typename w definicji, aby wskazać kompilatorowi, że B jest typem.

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

Widzę twój punkt widzenia. Przesunąłem definicję do pliku A.h. Dzięki. – LandonSchropp

0

odpowiedzi do aktualizacji:

Nie trzeba new wszystko w C++, w rzeczywistości, to byłoby najlepiej, jeśli nie, ponieważ wtedy trzeba by wyraźnie delete pamięć przydzielona lub użyj inteligentnych wskaźników.

Tak, tu jest Twój kod poprawione:

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

Jeśli chcesz new klasę A<C>, to trzeba użyć operator-> do wywołania metody:

A<C>::B b = a->getB(); 
Powiązane problemy