include 和 class类声明的区别

本文详细解释了在类定义中使用前向声明(forward declaration)与直接包含(class)的区别,包括减少编译依赖、隐藏实现、类间的相互引用及避免超前引用等问题。通过对比分析,帮助开发者在实际编程中做出合理的选择。

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

     在一个类的定义中要用到另外一个类,那么#include "Test.h"与class Test;二者什么区别?

1class Test 是一种前向声明(forward declaration),当你引入了前向声明时候,在声明之后,定义之前,类是一个不完全类型,引用它的函数的数据成员只能是指向它的指针或者引用.没有类的定义就无法创建类的对象。class T,则只可以让你使用T *、T &。

2、用申明而不用include的好处:去除编译依赖,减少编译消耗的时间,缩短编译时间。

3、用include会增加文件之间的依赖关系!!!如果一个文件"被依赖"的太多, 只要这个文件有修改, 依赖于这个文件的其它模块,文件都要重新编译一次!!!在编写大型程序的时候,一般要求尽量少使用头文件嵌套,即在头文件里面再包含其他头文件,这样可以减少头文件的相互依赖.另外,如果你程序中有很多类,只需编译修改过的类,可以过多的重新编译.
4、可以隐藏实现,比如你写一个Test的类,用Test.h写它的申明,在Test.cpp中写实现,编译出Test.o后则只需把Test.h和Test.o给人家,人家就可以用你的这个类。

      前向声明:一般情况下,类型要在使用前定义,但是在一些特殊情况下,这种要求无法满足,例如两个类相互包含, 即两个类互相使用对方提供的方法。 更一般的情况,类A和类B需要彼此互相引用,这样必然有一个类会先被定义,而另外一个类后被定义,这样在先被定义的类引用后被定义的类的时候,就导致了所谓的超前引用。    

### 的前置声明与模板结合使用的语法结构 在 C++ 中,的前置声明通常用于减少头文件之间的依赖关系,从而提高编译效率并降低耦合度。当涉及模板时,可以将模板作为参数传递给或函数,或者通过模板来定义本身。 以下是关于如何实现的前置声明与模板结合的具体方法: #### 前置声明模板 如果某个是一个模板,则可以在其他地方对其进行前置声明以便于后续使用。例如,在某些情况下可能只需要指针而不需要完整的定义,此时可以通过前置声明优化性能。 ```cpp // 声明一个名为 TemplateClass 的模板 (前置声明) template <typename T> class TemplateClass; // 定义另一个普通的 B,它只持有指向 TemplateClass<T> 的指针 class B { TemplateClass<int>* ptr; }; ``` 上述代码展示了如何对 `TemplateClass` 进行前置声明,并将其用作另一中的成员变量型[^1]。 #### 使用模板作为的友元 有时我们需要让特定型的模板成为某的朋友(friend)。这允许该模板访问私有部分的数据成员方法。 ```cpp template<typename U> class FriendTemplate; class MyClass { private: int secretValue = 42; // 将所有实例化的 FriendTemplate<U> 设置为朋友 template<typename U> friend class FriendTemplate; }; template<typename U> class FriendTemplate { public: void accessSecret(MyClass& obj) const { std::cout << "Accessing private member: " << obj.secretValue << '\n'; } }; ``` 在此例子中,任何由 `FriendTemplate` 实例化出来的对象都可以存取 `MyClass` 的内部数据[^2]。 #### 结合非型模板参数的例子 现代标准还支持非型模板参数,这意味着除了常规的数据型外还可以传入整数常量等值到模板里去定制行为模式。 ```cpp #include <iostream> template<std::size_t N> struct ArrayWrapper { double data[N]; constexpr std::size_t size() noexcept { return N; } double& operator[](std::size_t idx) { if(idx >= N){ throw std::out_of_range("Index out of bounds"); } return data[idx]; } }; int main(){ ArrayWrapper<3> array {}; try{ for(auto i=0u;i<=array.size(); ++i){ array[i]=static_cast<double>(i); std::cout<<array[i]<<" "; } }catch(const std::exception &e){ std::cerr<<"\nError:"<<e.what(); } } ``` 此片段创建了一个固定大小数组封装器,利用了非型模板参数指定长度。 ### 总结 以上介绍了几种常见场景下的 C++ 模板配合前置声明的应用方式,包括但不限于简单模板的提前告知、设置模板型别的友好权限以及引入数值作为额外约束条件的技术手段。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值