设为首页 加入收藏

TOP

详解C++ 类的前置声明的使用
2015-07-16 12:57:30 来源: 作者: 【 】 浏览:6
Tags:详解 前置 声明 使用

刚开始学习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()成员函数后这个类发生了什么改变,思考一下再回答。


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


上面的改变都是我们显式的、看得到的改变。还有一个隐藏的改变,想想是什么。。。
这个隐藏的改变是A的默认构造函数和默认拷贝构造函数发生了改变
由上面的改变可以看到,任何调用类A的成员变量或成员函数的行为都需要改变,因此,我们的a.h需要重新编译。


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


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


如果是这样的:


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


像我们这样前置声明类A


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


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


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


------------------------------分割线------------------------------


C语言梳理一下,分布在以下10个章节中:


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Python IDLE 清屏问题 下一篇编写C++类的条款

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: