2016-09-29 49 views
0

我有以下.HC++爲什麼這個前向聲明失敗?

class Book; //forward declaration of Book 

class Reader 
{ 
public: 
    Reader(); 

    void SetBook(Book); 

private: 

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

} 

一類和.cpp包含

#include "book.h" 

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

我不明白爲什麼這向前聲明將無法正常工作。 此外,它不會引發錯誤的「書」型在聲明

void SetBook (Book) 

任何建議,什麼是錯的,在這裏被使用?

+4

點擊此鏈接,這將是有幫助的。 http://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration – Vrana

回答

6

當您聲明指針或引用時,前向聲明就足夠了。因爲您的成員book_是Book類型,所以編譯器在處理標頭時需要定義Book

2

在頭文件Book是一個不完整類型(編譯器知道它是一種類型,但不是它有多大,或者它的成員是什麼)。

聲明函數(SetBook)的參數不完整,但聲明一個成員變量(book_),該類型需要完整(完全聲明)纔可以。特別是,編譯器需要知道Book有多大,以便它可以決定Reader有多大。

一個解決方案是使book_成爲一個智能指針(你可以使它成爲一個原始指針,但爲什麼會造成所有的內存處理頭痛?)。然後編譯器知道它需要一個指針(並且不關心被指向的對象有多大)。

0

這裏是一個替代的,看看它完全非正式的方式:

如果你只是寫標籤說:「親愛的鍋」,你只需要知道如何法術它。

現在,如果你想堅持的鍋標籤,把它帶回家吃飯呢,你需要知道織補鍋的樣子,以及如何將其打開

0

這裏的規則大拇指說到前置聲明或定義的問題:

正向聲明是標籤,定義是指打開盒子。

是否正在使用的類型的內部信息(即大小,存儲器佈局,成員數據/功能),或者只是其名稱

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