2012-03-19 1 views
37

Próbuję skompilować 2 klas w C++ za pomocą następującego polecenia:Zmienna C++ ma typ inicjatora, ale niekompletny?

g++ Cat.cpp Cat_main.cpp -o Cat

Ale pojawia się następujący błąd:

Cat_main.cpp:10:10: error: variable ‘Cat Joey’ has initializer but incomplete type

Może ktoś mi wyjaśnić, co to oznacza? Moje pliki zasadniczo tworzą klasę (Cat.cpp) i tworzą instancję (Cat_main.cpp). Oto mój kod źródłowy:

Cat.cpp:

#include <iostream> 
#include <string> 

class Cat; 

using namespace std; 

int main() 
{ 
    Cat Joey("Joey"); 
    Joey.Meow(); 

    return 0; 
} 

Cat_main.cpp:

#include <iostream> 
#include <string> 

using namespace std; 

class Cat 
{ 
    public: 
     Cat(string str); 
    // Variables 
     string name; 
    // Functions 
     void Meow(); 
}; 

Cat::Cat(string str) 
{ 
    this->name = str; 
} 

void Cat::Meow() 
{ 
    cout << "Meow!" << endl; 
    return; 
} 
+1

Nie można zadeklarować obiektów dla klas, których definicja nie jest jeszcze widoczna. – iammilind

+0

Jak powinienem był widoczny? –

+3

@Ken: Musisz dołączyć plik nagłówkowy. –

Odpowiedz

33

użyć do przodu deklarację kiedy trzeba kompletny typ.

Musisz mieć pełną definicję klasy, aby z niej skorzystać.

Zwykłym sposobem, aby go o to:

1) utworzyć plik Cat_main.h

2) Przesuń

#include <string> 

class Cat 
{ 
    public: 
     Cat(std::string str); 
    // Variables 
     std::string name; 
    // Functions 
     void Meow(); 
}; 

do Cat_main.h. Zauważ, że wewnątrz nagłówka usunąłem using namespace std; i kwalifikowany ciąg znaków z std::string.

3) zawierają ten plik w obu Cat_main.cpp i Cat.cpp:

#include "Cat_main.h" 
+0

Więc nie mogę rzucić definicji klasy w inny plik? –

+0

@Nie, nie to mówiłem. Przeczytaj odpowiedź jeszcze raz. –

+0

Czy zdefiniowałbym również funkcje klasy w pliku nagłówkowym? –

4

nie można zdefiniować zmienną niekompletnego typu. Musisz podać całą definicję Cat w zakresie przed możesz utworzyć zmienną lokalną w main. Zalecam przeniesienie definicji typu Cat do nagłówka i uwzględnienie go w jednostce tłumaczeniowej o wartości main.

+0

Więc muszę umieścić moją klasę 'Cat' w pliku z' main'? –

+4

@Ken: nie, musisz przeczytać książkę wprowadzającą o C++, w której wyjaśniona zostanie koncepcja nagłówków i plików źródłowych. –

+1

@Ken: Utwórz plik nagłówkowy z definicją klasy (i odpowiednich strażników), a następnie dołącz go zarówno z cat.cpp, jak i cat_main.cpp. –

9

To nie jest związane z przypadku Kena bezpośrednio, ale taki błąd może również wystąpić, jeśli skopiowane .h plik i zapomniał zmienić dyrektywę #ifndef. W tym przypadku kompilator po prostu pominie definicję klasy myśląc, że jest to duplikacja.

+1

Doskonały komentarz, myślę, że obejmuje najczęstszą przyczynę problemu. Wynika to z tego, że kopiowanie lub zmienianie nazwy pliku nagłówkowego i zapominanie o dyrektywie #ifndef jest trudne, podczas gdy inne odpowiedzi adresują zapominając o dodaniu instrukcji #include, która jest banalną pomyłką. – Vlad

1

Wystąpił podobny błąd i trafiłem na tę stronę podczas wyszukiwania rozwiązania.

Z Qt ten błąd może się zdarzyć, jeśli zapomnisz dodać krok QT_WRAP_CPP(...) do kompilacji, aby uruchomić kompilator meta object (moc). Włączenie nagłówka Qt nie jest wystarczające.