2016-09-29 7 views
0

Ich habe eine Klasse mit den folgenden .hC++ warum schlägt diese Vorwärtsdeklaration fehl?

class Book; //forward declaration of Book 

class Reader 
{ 
public: 
    Reader(); 

    void SetBook(Book); 

private: 

    Book book_; // Error Reader::book_ uses undefined class Book 

} 

und CPP enthält

#include "book.h" 

void Reader::SetBook(Book book) { this->book_ = book; } 
// Error C2440 cannot convert from Book to int 

Ich kann nicht sehen, warum diese Vorwärtsdeklaration würde nicht funktioniert. Auch dann, wenn es nicht einen Fehler für ‚Buch‘ Art wirft in der Erklärung

void SetBook (Book) 

Irgendwelche Vorschläge verwendet werden, was hier los?

+4

Folgen Sie diesem Link, wird es hilfreich sein. http://stackoverflow.com/questions/553682/when-cani-i-use-a-forward-declaration – Vrana

Antwort

6

Eine Vorwärtsdeklaration reicht aus, wenn Sie einen Zeiger oder eine Referenz deklarieren. Da Ihr Member book_ vom Typ Book ist, benötigt der Compiler die Definition von Book bei der Verarbeitung der Kopfzeile.

2

In der Header-Datei Book ist ein unvollständiger Typ (der Compiler weiß, es ist ein Typ, aber nicht, wie groß es ist, oder was seine Mitglieder sind).

Es ist in Ordnung, eine Funktion (SetBook) mit unvollständigen Argumenten zu deklarieren, aber um eine Membervariable (book_) zu deklarieren, muss der Typ vollständig (vollständig deklariert) sein. Insbesondere muss der Compiler wissen, wie groß Book ist, damit er entscheiden kann, wie groß Reader ist.

Eine Lösung besteht darin, book_ einen intelligenten Zeiger zu machen (Sie könnten es zu einem rohen Zeiger machen, aber warum alle Speicherbehandlung Kopfschmerzen?). Dann weiß der Compiler, dass er einen Zeiger benötigt (und es ist ihm egal, wie groß das auf das Objekt zeigt).

0

Hier ist eine alternative und völlig informelle Art und Weise, es zu sehen:

Wenn Sie nur Etiketten zu schreiben sagen „Pot of Honey“, die Sie gerade wissen müssen, wie man Zauber es.

Nun, wenn Sie das Etikett auf dem Topf halten wollen und bringen sie es zu Hause zu essen, müssen Sie wissen, was der verflixte Topf aussieht und wie es

0

Hier ist die Regel öffnen von Daumen, wenn es um das Problem der Vorwärtsdeklaration oder Definition geht:

Forward-Deklaration ist das Label und Definition bedeutet das Öffnen der Box.

Ob die interne Information (d. Größe, Speicherlayout Mitgliedsdaten/Funktion) des Typs verwendet werden, oder der Name nur

class Book; // forward declaration of Book. Right now we know nothing about Book's internal info except it's unique ID, i.e. the name of type: Book. 
Book *ptr; // OK, pointer's size is fixed and it has nothing to do with Book. 
Book **pptr; // Ok, same with previous  
ptr->someDataMember = bla; // ERROR, we don't know what is in a Book object. 
ptr->callDataFunc();  // ERROR 
++ptr; // ERROR, need to know the sizeof Book, since ++ptr equals to (char*)ptr + sizeof(Book) 
++pptr; // OK 
*pptr++; // OK, *pptr is a Book*, which size is fixed. 
**pptr++; // ERROR  

template<typename T> 
class DontUseT{}; 
DontUseT<Book> dut; // OK, we don't use Book's internal information here 

int foo(Book *b) { return sizeof(b);} // OK 
int foo(Book&b) { return 0;} // OK 
int foo(Book&b) { return sizeof(Book);} // ERROR 
int foo(Book); // OK 
int foo(Book) {} // ERROR, inside the definition it's supposed to access its arguments  
Verwandte Themen