我的意思是我真正的头文件看起来像这样:
#include "some_internal_class.h"
class MyLibrary {
Type private_member;
void private_function();
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Run Code Online (Sandbox Code Playgroud)
现在我想生成一个包含所有必要定义的动态库.我想用它来发送一个标题,而不是发送我库中的每一个标题.
所以我想我可以像这样创建一个瘦小版本的标题:
class MyLibrary {
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Run Code Online (Sandbox Code Playgroud)
标题只是声明无论如何正确吗?它们永远不会传递给编译器.我已经宣布了用户将使用的内容.
那可能吗?如果没有,为什么不呢?
这是一个定义规则违规.你偏离一个令牌的那一刻.
在程序中可以有多个类类型的定义,[...]只要每个定义出现在不同的翻译单元中,并且定义满足以下要求即可.鉴于这样一个名为D的实体在多个翻译单元中定义,那么
- D的每个定义应由相同的令牌序列组成; 和
如果您违反ODR,您的程序可能会轻易破坏.而你的构建系统根本没有义务甚至警告你.
无论如何,标题只是声明,对吗?它们永远不会传递给编译器。我已经声明了用户将使用什么。
不会。标头是源代码的一部分,与源文件一起编译。它们包含编译器理解如何使用代码(在您的情况下,使用 class MyLibrary)所需的信息。
例如,您希望库用户能够创建 class 的对象MyLibrary,因此您导出构造函数。然而,这还不够:编译器需要知道要创建的对象的大小,除非指定所有字段,否则这是不可能的。
在实践中,决定向库用户公开什么以及隐藏什么作为实现细节是一个难题,这需要对库的使用和语义进行详细检查。如果您确实想隐藏类内部作为实现细节,这里有一些常见的选项: