C++类的前向声明的学习

 
2013-04-06 17:12:18
原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://liam2199.blog.51cto.com/2879872/1172175

 http://liam2199.blog.51cto.com/2879872/1172175原文链接

    假设声明两个类A和B,如果需要在A.h中定义B类对象,B b_; 势必要包含# include "B.h",而B类中需要定义A类对象A a_; 也要包含B.h,但是相互包含是不允许的,称为环形引用,这时候就用到了前向声明。

    在B类中进行前向声明:

  
  
  1. class A; 

    B.h中就不用包含A.h,但是前提是,不能定义对象,只能定义指针或引用。

 

A类

 

  
  
  1. //A.h 
  2.  
  3. # ifndef _A_H_ 
  4. # define _A_H_ 
  5.  
  6. # include "B.h" 
  7.  
  8. class A 
  9.     A(void); 
  10.     ~A(void); 
  11.      
  12.     B b_;  //要包含B.h 
  13. }; 
  14.  
  15. # endif //_A_H 

B.h

 

  
  
  1. //B.h 
  2. # ifndef _B_H_ 
  3. # define _B_H_ 
  4. //前向声明,不能实例化对象 
  5. class A;  // 就不需要包含A.h,要求不能定义对象,只能给定义指针和引用 
  6. //因为我们不知道类长声明样子,就无法为其分配内存 
  7.  
  8. class B 
  9.     B(void); 
  10.     ~B(void); 
  11.  
  12.     void fun(A& a)//只能是指针或引用 
  13.     { 
  14.         ; 
  15.     } 
  16.     //前向声明的类不能实例化对象 
  17.     A* a_;  // 
  18. }; 
  19.  
  20. # endif //_B_H_ 

B.cpp

 

  
  
  1. B.cpp 
  2.  
  3. # include "B.h" 
  4. # include "A.h" 
  5.  
  6. B::B(void
  7.  
  8. B::~B() 
  9.  

 总结:

     前向声明的类不能实例化对象。

前向声明的定义:有些时候我们可以声明一些类但是并不去定义它,当然这个类的作用也很有限了。

比如class foo;

声明一个foo类,这个声明,有时候也叫做前向声明(forward declaration),在声明完这个foo类之后,定义完这个foo类之前的时期,foo类是一个不完全的类型(incomplete type),也就是说foo类是一个类型,但是这个类型的一些性质(比如包含哪些成员,具有哪些操作)都不知道。

因此这个类的作用也很有限.

(1)不能定义foo类的对象。

(2)可以用于定义指向这个类型的指针或引用。(很有价值的东西)

(3)用于声明(不是定义)使用该类型作为形参或者返回类型的函数。

正因为有前向声明的存在,我们在很多时候可以简便的做一些事情。

在c++中,如果要为类编写头文件的话,一般是要#include一堆头文件的,但利用前向声明和c++编译器的特性,其中大部分是不需要的。

c++编译器做的事情主要是:1.扫描符号;2.确定对象大小。

所以很多时候并不需要将类都include进来。

比如:

(1)由于所有对象类型的应用所占用的空间都是相同大的,所以c++编译器很好确认对象大小。

class string;

class Sample

{

private:

string &s;

};

这里只需要做一个string的前向声明就可以了,不需要#include <string>

(2)由于所有类型的指针也是相同大小的。所以与(1)类似,也可以只做前向声明就好。

(3)声明成员函数的形参或者是返回类型,也可以利用前向声明的性质。

class string;

class foo;

class Sample

{

public:

foo foo_test(foo &);

private:

string &s;

foo *f;

};

这里,我根本没有定义一个foo类,但是还是可以这样用,因为成员函数不占类对象的大小,所以c++编译器还是可以确定对象的大小。

前向声明的作用在于告诉编译器这个一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值