【C++基础】C++之类的前置声明

转载 2013年12月02日 17:21:32

c++ 之类的前置声明


注:本文转自http://software.intel.com/zh-cn/blogs/2010/05/04/c-2


刚开始学习c++的人都会遇到这样的问题:


定义一个类 class A,这个类里面使用了类B的对象b,然后定义了一个类B,里面也包含了一个类A的对象a,就成了这样:



一编译,就出现了一个互包含的问题了,这时就有人跳出来说,这个问题的解决办法可以这样,在a.h文件中声明类B,然后使用B的指针。


然后,问题就解决了。

但是,有人知道问题是为什么就被解决的吗,也就是说,加了个前置声明为什么就解决了这样的问题。下面,让我来探讨一下这个前置声明。

类的前置声明是有许多的好处的。

我们使用前置声明的一个好处是,从上面看到,当我们在类A使用类B的前置声明时,我们修改类B时,只需要重新编译类B,而不需要重新编译a.h的(当然,在真正使用类B时,必须包含b.h)。

另外一个好处是减小类A的大小,上面的代码没有体现,那么我们来看下:



我们看上面的代码,类B的大小是12(在32位机子上)。

如果我们在类A中包含的是B的对象,那么类A的大小就是12(假设没有其它成员变量和虚函数)。如果包含的是类B的指针*b变量,那么类A的大小就是4,所以这样是可以减少类A的大小的,特别是对于在STL的容器里包含的是类的对象而不是指针的时候,这个就特别有用了。

在前置声明时,我们只能使用的就是类的指针和引用(因为引用也是居于指针的实现的)。

那么,我问你一个问题,为什么我们前置声明时,只能使用类型的指针和引用呢?

如果你回答到:那是因为指针是固定大小,并且可以表示任意的类型,那么可以给你80分了。为什么只有80分,因为还没有完全回答到。

想要更详细的答案,我们看下下面这个类:


我们看下上面定义的这个类A,其中_b变量和get_b()函数是新增加进这个类的。

那么我问你,在增加进_b变量和get_b()成员函数后这个类发生了什么改变,思考一下再回答。

好了,我们来列举这些改变:

第一个改变当然是增加了_b变量和get_b()成员函数;

第二个改变是这个类的大小改变了,原来是4,现在是8。

第三个改变是成员_a的偏移地址改变了,原来相对于类的偏移是0,现在是4了。

上面的改变都是我们显式的、看得到的改变。还有一个隐藏的改变,想想是什么。。。

这个隐藏的改变是类A的默认构造函数和默认拷贝构造函数发生了改变。

由上面的改变可以看到,任何调用类A的成员变量或成员函数的行为都需要改变,因此,我们的a.h需要重新编译。

如果我们的b.h是这样的:



那么我们的b.h也需要重新编译。

如果是这样的:


那么我们的b.h就不需要重新编译。

像我们这样前置声明类A:

class A;

是一种不完整的声明,只要类B中没有执行需要了解类A的大小或者成员的操作,则这样的不完整声明允许声明指向A的指针和引用。

而在前一个代码中的语句

A a;

是需要了解A的大小的,不然是不可能知道如果给类B分配内存大小的,因此不完整的前置声明就不行,必须要包含a.h来获得类A的大小,同时也要重新编译类B。

再回到前面的问题,使用前置声明只允许的声明是指针或引用的一个原因是只要这个声明没有执行需要了解类A的大小或者成员的操作就可以了,所以声明成指针或引用是没有执行需要了解类A的大小或者成员的操作的。

C++模板类的前置声明

template class LinkedStack;templateclass Node{friend class LinkedStack;private: T data; Node *link;}...
  • fuli1215
  • fuli1215
  • 2011年04月13日 15:24
  • 5447

c++之类的前置声明

        原创文章,转载请注明出处,谢谢!               作者:清林,博客名:飞空静渡 刚开始学习c++的人都会遇到这样的问题:定义一个类 class A,这个类里面使用了类B的对...
  • fjb2080
  • fjb2080
  • 2010年04月27日 12:36
  • 5335

【总结】C++前置声明

总结来说: 1)降低模块的耦合。因为隐藏了类的实现,被隐藏的类相当于原类不可见,对隐藏的类进行修改,不需要重新编译原类。 2)降低编译依赖,提高编译速度。指针的大小为(32位)或8(64位),X发...
  • qq_37660535
  • qq_37660535
  • 2017年06月09日 15:07
  • 129

C++之类的前置声明

在使用前置声明时,只能使用指针或者引用,因为在这
  • taozi1234567
  • taozi1234567
  • 2014年10月18日 14:59
  • 213

【C++学习与应用总结】2: 关于类型前置声明

本文总结了c++中前置声明的写法及注意事项,列举了哪些情况可以用前置声明来降低编译依赖。...
  • elloop
  • elloop
  • 2015年12月04日 07:51
  • 5356

c++ 之类的前置声明

http://software.intel.com/zh-cn/blogs/2010/05/04/c-2/ c++ 之类的前置声明 清林 于 星期二, 04/05/2010 - 10:02 提交 ...
  • nklinux
  • nklinux
  • 2013年12月08日 12:29
  • 401

C++中如何设置前置声明

转载自 http://www.cnblogs.com/alaigle/archive/2012/06/05/2536610.html在编写C++程序的时候,偶尔需要用到前置声明(Forward dec...
  • u010339647
  • u010339647
  • 2017年09月05日 14:53
  • 139

C++类前置声明解决类之间互相包含的问题

作者:朱金灿 http://blog.csdn.net/clever101       类的前置声明(forward declaration)和包含头文件(#include)的区别常...
  • hewei0241
  • hewei0241
  • 2014年05月02日 21:49
  • 1258

c++中namespace和前置声明

前置声明一般用于要在一个类中使用另一个类,而另一个类的声明在后面或者其他文件中时 如类A和B class A{ private:       B *b; }; class B{ };这里类B在类A后...
  • hhm853610070
  • hhm853610070
  • 2017年03月20日 15:59
  • 872

C/C++前置声明和避免隐藏包含

1.C/C++.h文件中使用前置声明,减少大型项目的编译时间和支持相互包含。 判断使用前置声明的条件: 1)类指针/类引用数据成员,静态的类对象可以使用前置声明,函数参数/返回值的类型声明为类对象。 ...
  • Blues1021
  • Blues1021
  • 2015年04月10日 20:24
  • 628
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【C++基础】C++之类的前置声明
举报原因:
原因补充:

(最多只允许输入30个字)