c++中的前向声明

本文介绍了C++中的前向声明,包括其好处、定义、限制和实例。前向声明允许在未定义类的情况下使用类的指针,帮助编译器建立正确的符号表。在类成员、指针参数和成员函数返回类型中可以应用前向声明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整理于:

http://blog.youkuaiyun.com/heyutao007/article/details/6649741

http://blog.sina.com.cn/s/blog_68d90fdb0100yapr.html

1. 前向声明好处

1)不必要的#include   会增加编译时间. 
2)混乱随意的#include可能导致循环#include,可能出现编译错误.

2. 定义

      可以声明一个类而不定义它。这个声明,有时候被称为前向声明(forward declaration)。在声明之后,定义之前,类Screen是一个不完全类型(incompete type),即已知Screen是一个类型,但不知道包含哪些成员。不完全类型只能以有限方式使用,不能定义该类型的对象,不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。
      类的前向声明之适用于指针和引用的定义,如果是普通类类型就得使用include了。
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class A;   
  2. class B   
  3. {   
  4. public:   
  5. A* m_a; //(不能A m_a)   
  6. }   

3. 前向声明的限制

(1)不能定义foo类的对象;
(2)可以用于定义指向这个类型的指针或引用。(很有价值的东西);
(3)用于声明(不是定义)使用该类型作为形参或者返回类型的函数。

4. 实例

c++编译器做的事情主要是:1.扫描符号;2.确定对象大小。
所以很多时候并不需要将类都include进来。
比如:
(1)由于所有对象类型的引用所占用的空间都是相同大的,所以c++编译器很好确认对象大小。
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class string;  
  2. class Sample  
  3. {  
  4. private:  
  5. string &s;  
  6. };  
这里只需要做一个string的前向声明就可以了,不需要#include <string>


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


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

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class string;  
  2. class foo;  
  3. class Sample  
  4. {  
  5. public:  
  6. foo foo_test(foo &);  
  7. private:  
  8. string &s;  
  9. foo *f;  
  10. };  


这里,我根本没有定义一个foo类,但是还是可以这样用,因为成员函数不占类对象的大小,所以c++编译器还是可以确定对象的大小。
      前向声明的作用在于告诉编译器这个一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。

(4) 即使前向声明一个没有定义的类,devc++也可以编译通过,如下所示:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. struct B;  
  5. class foo;  
  6.   
  7. B func();  
  8.   
  9. class A  
  10. {  
  11.     public:  
  12.         B* t;  
  13.           
  14.     public:  
  15.         foo foo_test( foo & );  
  16. };  
  17.   
  18.   
  19. class B  
  20. {  
  21.     public:  
  22.         int a;  
  23.           
  24.     public:  
  25.         B() {}  
  26.           
  27.         virtual int add()  
  28.         {  
  29.             return 0;     
  30.         }  
  31.           
  32.         static int c;  
  33.           
  34. };  
  35.   
  36. int main()  
  37. {  
  38.     A a;  
  39.     return 0;  
  40. }  


上面代码也可以编译运行,即使没有看到class foo的定义;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值