C++ 前置声明

简介:

问题:

    最近遇到了两个类A、B相互调用的情况,于是想当然的在两个类A和B的头文件中 #include 了所需的头文件,当然结果编译报错了。为什么呢,A需要B,B需要A,形成了循环,违反了程序的确定性原则。代码如下图所示:


wKiom1e-ks-TW-Y1AAAtg2z-LBk283.png


    如这样相互包含的问题,可以使用前置声明来解决。即:在头文件中声明该类,在实现文件中包含该类。如下图所示:


wKioL1e-libSQ_moAAB4xnudOQ4671.png


解析:

    为什么这样使用前置声明,即在AAA.h中声明class BBB; 在BBB.h中声明class AAA; 且成员变量写为所声明类的指针变量, 便不会产生相互包含的错误呢?

    原因在于:class BBB;这种方式仅仅是一种符号声明,告诉编译器存在BBB这个类,不会去确定BBB这个类的所占资源(内存)大小和这个类的实现。

    上图中可以看到在AAA.h中定义的是BBB的指针变量或引用变量,而不是普通的BBB变量,这是因为定义指针变量或引用变量,编译器只需给该变量分配4字节(32位程序)内存,而不用管BBB对象具体需要占用多少内存,也不去确定该类的构造函数是如何实现的,这些事情是在创建该对象(即AAA.cpp中:b = new BBB;)时才会去确定;

    但是若定义普通的BBB变量:BBB b; 的话,编译器需要知道b变量占用了多大内存,构造函数如何实现,然后计算需要为AAA类分配内存大小,这样只是声明Class BBB;就不行了,否则会报错:"使用了未定义的类BBB”,解决办法是#include"BBB.h",又回到了开始的问题。

    同理,BBB.h中关于AAA的声明及变量定义也是如此。


优点:

    使用前置变量,即:在头文件中声明该类,在实现文件中包含该类。有其一定的优势,以AAA类为例:

(1)BBB修改后重新编译的话,因为是前置声明,所以不需要重新编译AAA.h;

(2)定义的成员变量为指针变量或引用变量,内存固定增加了4(32位程序),减少了AAA类的内存占用

   大小,这体现在STL的容器里包含是类的对象还是指针的时候特别有用。


附录:

    这里附上成员变量声明为"引用变量"时的用法代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//AAA.h
#pragma once
 
class  BBB;
 
class  AAA
{
public :
     AAA(BBB &x);
     ~AAA();
     
private :
     BBB &b;
};
 
#include "AAA.h"
AAA::AAA(BBB &x) : b(x)
{
}
 
AAA::~AAA( void )
{
}
 
 
 
 
//BBB.h
#pragma once
 
class  AAA;
 
class  BBB
{
public :
     BBB( void );
     ~BBB( void );
     void  NewAAA();
 
private :
     AAA *a;
};
 
 
//BBB.cpp
#include "BBB.h"
#include "AAA.h"
 
BBB::BBB()
{
     NewAAA();
}
 
BBB::~BBB( void )
{
}
 
void  BBB::NewAAA()
{
  BBB b;
  a =  new  AAA( b );
}
 
 
//main.cpp
#include <iostream>
 
int  main()
{
     return  0;
}




本文转自 006玩命 51CTO博客,原文链接:http://blog.51cto.com/weiyuqingcheng/1842469,如需转载请自行联系原作者
相关文章
|
1月前
|
算法 程序员 C语言
【C++ 运算符重载】深入理解C++迭代器中的前置与后置++操作符
【C++ 运算符重载】深入理解C++迭代器中的前置与后置++操作符
85 0
|
编译器 C++
C++ Trick:什么时候需要前置声明?
经常有C++开发的小伙伴提问: C++中要使用类A时,什么时候#include "a.h",什么时候用class A前置声明呢?
215 0
|
3天前
|
安全 编译器 C++
【C++】学习笔记——类和对象_5
【C++】学习笔记——类和对象_5
17 9
|
3天前
|
编译器 C++
【C++】学习笔记——类和对象_4
【C++】学习笔记——类和对象_4
14 6
|
3天前
|
存储 编译器 C++
【C++】学习笔记——类和对象_3
【C++】学习笔记——类和对象_3
17 6
|
3天前
|
存储 编译器 C语言
【C++】学习笔记——类和对象_2
【C++】学习笔记——类和对象_2
14 3
|
3天前
|
存储 编译器 C语言
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
8 2
|
2天前
|
C++
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
4 0
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)