c ++为什么这个前向声明失败了?

时间:2016-09-29 07:41:24

标签: c++

我有一个包含以下内容的类.h

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

我不明白为什么这个前瞻性声明不起作用。 此外,它不会为声明中使用的“Book”类型引发错误

void SetBook (Book )

有什么建议吗?在这里?

4 个答案:

答案 0 :(得分:6)

声明指针或引用时,前向声明就足够了。由于您的成员book_属于Book类型,因此编译器在处理标题时需要Book的定义。

答案 1 :(得分:2)

在头文件中Book不完整类型(编译器知道它是一种类型,但不知道它有多大,或者它的成员是什么)。

可以使用不完整类型的参数声明函数(SetBook),但要声明成员变量(book_),类型需要完整(完全声明)。特别是,编译器需要知道Book有多大,以便它可以决定Reader的大小。

一种解决方案是让book_成为一个智能指针(你可以把它变成一个原始指针,但为什么要创建所有的内存处理头疼?)。然后编译器知道它需要一个指针(并不关心指向对象的大小)。

答案 2 :(得分:0)

以下是另一种非正式的方式:

  

如果你只是在写“Pot of Honey”的标签,你只需要知道如何拼写

     

现在,如果你想把标签贴在锅上并带回家吃它,你需要知道这个罐子是什么样子以及如何打开它

答案 3 :(得分: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