我正在开发一个 C++ 项目,其中有一个涉及类型 A 和 B 的类型层次结构。我希望实现封装,使得类型 A 仅在类型 B 的上下文中可见,并且对外部访问保持隐藏。此外,我希望类型 B 在包含定义它的头文件时可以访问。这是我的想法:
在头文件
B.hpp
中,我有以下代码:
#ifndef B_HPP
#define B_HPP
#include "X.hpp"
// Declaration or definition of type A
enum class A : underlying_type { ... }; // I want to hide this from external access
// Definition of type B, which uses type A
using B = X<A>; // I want this to be visible when including B.hpp
#endif // B_HPP
您能否指导我如何在 C++ 中实现这种封装,同时确保类型 B 在包含
B.hpp
标头时仍然可访问?
我研究了这个主题,虽然我发现了一些相关问题,但它们没有解决我的具体情况。我正在寻找有关如何构建标题的指导。
我尝试实现类型 A 封装在类型 B 中,如我原始问题中的代码片段所述。我期望通过在头文件 B.hpp 中声明类型 A,然后在类型 B 的定义中使用它,我将能够将类型 A 封装在类型 B 的范围内。具体来说,我期望类型 A 不会在 B.hpp 头文件外部可见,而类型 B 在包含头文件时可以访问。
感谢您的协助!
标头中使用的所有内容都必须至少为
forward declared
,因此对标头可见。没有作用域机制(在 c++20
模块之前)来将符号的可见性降低到仅当前标头。标题可见的所有内容对于翻译单元也将可见 #include
标题。
唯一的方法是通知标头的使用者该符号仅以某种方式供内部使用。
这可以通过多种方式完成:
#include <X.h>
// hide the implementation in another header
#include <impl/A.h>
using B = X<A>;
或
#include <X.h>
namespace please_do_not_touch {
// hide it in an internal namespace
enum class A : ... { ... };
}
using B = X<please_do_not_touch::A>;
或
#include <X.h>
// discourage usage by uglyfying the name signalizing internal symbol
enum class UglyInternalName : ... { ... };
using B = X<UglyInternalName>;
或者如果可能的话(不太可能,因为它是模板,除非使用模板专门化和显式模板实例化)
#include <X.h>
// Forward declare the type and define in source file making the enum values unusable to others
enum class A : ...;
using B<A>;