C++类的前置声明(二)

看完《Effective C++》条款31有感。。

假设有一个Date类

//Date.h
class Date {  
private:  
    int year, month, day;  
};  


如果有个Task类的定义要用到Date类,有两种写法

其一

//Task1.h

class Date;  
class Task1 {  
public:  
    Date getData();  
};  

 

其二

//Task2.h

#include "Date.h"  
class Task2 {  
public:  
    Date getData();  
};  


一个采用前置声明,一个采用#include<Date.h>加入了Date的定义。两种方法都能通过编译。但是 Task1.h 这种写法更好。如果Date.h 的 private 成员变量改变,比如变成 double year, month, day; ,Task1.h 不需要重新编译,而 Task2.h 就要重新编译,更糟的是如果 Task2.h 还与其他很多头文件有依赖关系,就会引发一连串的重新编译,花费极大的时间。可是事实上改变一下写法就可以省去很多功夫。

所以能用前置声明代替#include 的时候,尽量用前置声明

有些情况不能用前置声明代替#include

比如Task1.h改成


class Date;  
class Task1 {  
public:  
    Date d;  
};  

会编译错误,因为Date d定义了一个Date类型变量,编译器为d分配内存空间的时候必须知道d的大小,必须包含定义Date类的Date.h文件。

这是可以采用指针来代替


class Date;  
class Task1 {  
public:  
    Date *d;  
};  

指针的大小是固定的。在32位机上是4字节,64位机上是8字节。这时编译Task1的时候不需要Date的大小,所以和Date的定义无关。

何时可以用前置声明代替#include

可参考(https://blog.csdn.net/Jxianxu/article/details/83688552

上述例子可以说明

如果使用object reference 或 object point 可以完成任务,就不要用object

这样可以尽最大可能避免#include

为声明式和定义是提供不同的头文件 

在函数库的设计过程中,接口的设计就要遵循上述准则。

一个接口的头文件是这样的

//interface.h

[cpp] view plain copy
class Date;  
class Address;  
class Email;  
Date getDate();  


如果客户只用到Date类,编译器就只会去编译Date.h,而不去编译Address.h,Email.h 等等文件。
原文:https://blog.csdn.net/fallStones/article/details/6266632 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中,可以使用声明前置(forward declaration)来解决互相依赖的之间的编译问题。声明前置可以让编译器知道某个的存在,而无需包含该的头文件。 具体来说,如果一个 A 依赖于另一个 B,而 B 又依赖于 A,那么在定义这两个时,就会产生循环依赖的问题。此时,我们可以使用声明前置来解决这个问题。 例如,假设有两个 `ClassA` 和 `ClassB`,它们互相依赖,可以这样来声明前置: ```cpp // ClassA.h 文件 #pragma once // 前置声明 ClassB class ClassB; class ClassA { public: void func(ClassB* b); }; // ClassB.h 文件 #pragma once // 前置声明 ClassA class ClassA; class ClassB { public: void func(ClassA* a); }; ``` 在上面的代码中,我们使用了 `class ClassB;` 和 `class ClassA;` 来声明前置,而不是包含的头文件。这样,编译器就能够知道这两个的存在,从而解决了循环依赖的问题。 需要注意的是,如果使用了声明前置,那么只能在函数参数、函数返回值或者指针成员变量等地方使用这个。如果需要使用该的具体实现,还需要包含该的头文件。例如,在 `ClassA.cpp` 文件中实现 `ClassA` 的成员函数时,需要包含 `ClassB.h` 头文件: ```cpp // ClassA.cpp 文件 #include "ClassA.h" #include "ClassB.h" void ClassA::func(ClassB* b) { // 使用 ClassB 的具体实现 } ``` 总之,声明前置可以解决互相依赖的之间的编译问题,提高代码的可读性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值