在C++中,如何在头文件中声明一个数据结构,而它是在源文件中定义的?
In C++, how to declare a data structure in header file , while it is defined in source file?
假设我想使用 typedef 在源文件中定义一个新的集合 MyTypeSet,其中包含自定义的散列和比较器函数。我想隐藏源文件中的所有实现细节。
typedef std::unordered_set<MyType, MyTypeHash, MyTypeKeyEqual>
MyTypeSet;
然后我想在头文件中声明MyTypeSet,供其他模块使用。但我不想公开 MyTypeHash 和 MyTypeKeyEqual
只是想不出正确的语法。
typedef
无法做到这一点。 MyTypeSet
的用户需要能够看到 MyType
、MyTypeHash
和 MyTypeKeyEqual
的完整定义才能知道如何编译 MyTypeSet
。
有几种方法用于从实现细节中区分模板代码的 public 接口:
- 将实现细节放在另一个 header ("MyTypeImpl.hpp") 中,它包含在 public header.
中
- 将私有实现类型放在名为
detail
、private
或类似名称的命名空间中。
- 用下划线字符破坏私有名称,如
MyTypeHash_
。 (这点可以在MSVC标准库中看到不少)
如果绝对有必要对 MyTypeHash
和 MyTypeKeyEqual
保密,那么可以将 MyTypeSet
声明为 class,它只有最终需要的方法用户。然后 MyTypeSet
可以使用 pImpl idiom 将 std::unordered_set
作为仅在源文件中可见的成员变量。 MyTypeSet
的所有方法都将通过调用 std::unordered_set
来实现。
这样的 MyTypeSet
不能具有与 std::unordered_set
完全相同的 public 接口,因为 std::unordered_set
将其散列和键类型公开为成员类型。
假设我想使用 typedef 在源文件中定义一个新的集合 MyTypeSet,其中包含自定义的散列和比较器函数。我想隐藏源文件中的所有实现细节。
typedef std::unordered_set<MyType, MyTypeHash, MyTypeKeyEqual>
MyTypeSet;
然后我想在头文件中声明MyTypeSet,供其他模块使用。但我不想公开 MyTypeHash 和 MyTypeKeyEqual
只是想不出正确的语法。
typedef
无法做到这一点。 MyTypeSet
的用户需要能够看到 MyType
、MyTypeHash
和 MyTypeKeyEqual
的完整定义才能知道如何编译 MyTypeSet
。
有几种方法用于从实现细节中区分模板代码的 public 接口:
- 将实现细节放在另一个 header ("MyTypeImpl.hpp") 中,它包含在 public header. 中
- 将私有实现类型放在名为
detail
、private
或类似名称的命名空间中。 - 用下划线字符破坏私有名称,如
MyTypeHash_
。 (这点可以在MSVC标准库中看到不少)
如果绝对有必要对 MyTypeHash
和 MyTypeKeyEqual
保密,那么可以将 MyTypeSet
声明为 class,它只有最终需要的方法用户。然后 MyTypeSet
可以使用 pImpl idiom 将 std::unordered_set
作为仅在源文件中可见的成员变量。 MyTypeSet
的所有方法都将通过调用 std::unordered_set
来实现。
这样的 MyTypeSet
不能具有与 std::unordered_set
完全相同的 public 接口,因为 std::unordered_set
将其散列和键类型公开为成员类型。