C++类的前向声明(forward declaration)

一、使用场景

假设有两个类A和B,类A要将类B的对象(或者指正)作为自己的成员使用,并且类B将类A的对象(或者指针)作为自己可以访问的数据,那么这个时候要在a.h中include b.h,同时在b.h 中要include a.h,但是相互包含是不可以的,这个时候就要用到类的前向声明了。

类的前向声明是利用了编译器的特性,编译器在编译的过程中只需要知道各个元素的名称和相应的大小就可以。而在c++中每一个类的大小是固定的,这个时候使用前向声明的类就可以通过编译器。

比如class foo;

声明一个foo类,这个声明,有时候也叫做前向声明(forward declaration),在声明完这个foo类之后,定义完这个foo类之前的时期,foo类是一个不完全的类型(incomplete type),也就是说foo类是一个类型,但是这个类型的一些性质(比如包含哪些成员,具有哪些方法)都不知道。所以不能通过这个前向声明的类的指针或者对象去操作自己的成员。


二、使用方法

假设B类中已经包含了a.h,那么在A类中不能再包含b.h,要在A类中前向声明类B,如下

# include "B.h" 
class A 
{ 
    A(void); 
    ~A(void);     
    B b_;  //要包含B.h 
}; 
//B.h 
class A;
class B 
{ 
    B(void); 
    ~B(void); 
    void fun(A& a)//只能是指针或引用 
    { 
    } 
    //前向声明的类不能实例化对象 
    A* a_;  // 
}; 

三、注意问题

1. 前向声明的类不能定义对象

2. 可以用于定义指向这个类型的指针和引用。

2. 用于申明使用该类型作为形参或返回类型的函数

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 的具体实现 } ``` 总之,声明置可以解决互相依赖的之间的编译问题,提高代码的可读性和可维护性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值