在 C++ 中,当你使用某个类的指针或引用而不是该类的实例时,你可以采用前向声明(forward declaration)而不必包括完整的类定义。
这是因为指针和引用的大小和对齐要求在编译时是已知的,而具体类的内容对于仅仅声明一个指向该类型的指针或引用来说是不必要的。
对于给定代码:
cpp
#pragma once
#include "noncopyable.h"
#include <vector>
class Channel;
// muduo库中多路事件分发器的核心IO复用模块
class Poller : noncopyable {
public:
using ChannelList = std::vector<Channel*>;
protected:
private:
};
前向声明和指针
cpp
using ChannelList = std::vector<Channel*>;
在这个声明中,我们定义了一个名为 ChannelList
的类型,它是一个指向 Channel
对象的指针的向量。因为我们只使用了 Channel*
(指针类型),而不是 Channel
本身,编译器不需要知道 Channel
类的具体定义。
所以我们只需要讲 Channel
被前向声明为一个类:
cpp
class Channel;
为什么使用指针类型不需要包含头文件
何时需要包含头文件
尽管前向声明在许多情况下都很有用,但在以下情况中,你仍然需要包含头文件:
- 直接使用类对象:
如果你需要直接声明一个 Channel 类型的对象,而不仅仅是指针或引用,那么你需要包含 Channel 类的头文件。
- 访问类成员:
如果你需要访问 Channel 类的成员(函数或变量),你需要知道这些成员的定义,因此需要包含头文件。
- 继承类:
如果你的类需要继承 Channel 类,你需要完整的类定义,这意味着你必须包含头文件。
示例代码
以下是如何使用前向声明和头文件包含的示例:
Poller.h:
cpp
#pragma once
#include "noncopyable.h"
#include <vector>
class Channel; // 前向声明
class Poller : noncopyable {
public:
using ChannelList = std::vector<Channel*>;
protected:
private:
};
Channel.h:
cpp
#pragma once
class Channel {
public:
// Channel 类的定义
};
Poller.cpp:
cpp
#include "Poller.h"
#include "Channel.h" // 在需要使用 Channel 类定义的地方包含头文件
// Poller 类的实现