c++ - 显式直接#include 与非契约传递#include

标签 c++ header include c++17

假设我们有这个头文件:

MyClass.hpp

#pragma once
#include <vector>

class MyClass
{
public:
    MyClass(double);

    /* ... */

private:
    std::vector<double> internal_values;
};

现在,每当我们使用 #include "MyClass.hpp"在其他一些 hpp 或 cpp 文件中,我们实际上还 #include <vector> ,尽管我们不需要它。我说不需要它的原因是 std::vector仅在 MyClass 内部使用,但根本不需要与此类进行实际交互

结果,我可以写

版本 1:SomeOtherHeader.hpp

#pragma once
#include "MyClass.hpp"

void func(const MyClass&, const std::vector<double>&);

而我可能应该

版本 2:SomeOtherHeader.hpp

#pragma once
#include "MyClass.hpp"
#include <vector>

void func(const MyClass&, const std::vector<double>&);

防止对MyClass 内部工作的依赖.还是应该?

我显然意识到 MyClass需要<vector>去工作。所以这可能更像是一个哲学问题。但是能够决定在导入时暴露哪些 header (即限制加载到命名空间中的内容)不是很好吗?这样每个标题都需要#include 需要什么,而不是隐含地包含另一个 header 在链中需要的东西?

也许人们也可以对即将推出的 C++20 模块有所了解,我相信这些模块可以解决这个问题的某些方面。

最佳答案

to prevent a dependency on the internal workings of MyClass. Or should I?

是的,出于这个原因,您应该这样做。除非你想指定 MyClass.hpp 保证包含 <vector> ,你不能依赖一个,包括另一个。并且没有充分的理由被迫提供这样的保证。如果没有这样的保证,那么您将依赖 MyClass.hpp 的实现细节,该细节可能会在未来发生变化,这会破坏您的代码。

I obviously realise that MyClass needs vector to work.

是吗?它不能使用例如 boost::container::small_vector代替?

In this example MyClass needs std::vector

但是 MyClass future 的需求呢?类(class)不断发展,类(class)今天需要的东西并不总是与明天类(class)需要的一样。

But would it not be good to be able to decide which headers get exposed when importing

不可能防止传递包含。

C++20 中引入的模块是一个可以用来代替 pp-inclusion 的特性,旨在帮助解决这个问题。

现在,您可以通过使用 PIMPL 模式(“指向实现的指针”)来避免包含任何实现细节依赖项。但是 PIMPL 引入了一个间接层,更重要的是,它需要动态分配,这对性能有影响。根据具体情况,这些影响可能可以忽略不计或显着。

关于c++ - 显式直接#include 与非契约传递#include,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56596929/

相关文章:

c - #include header with C declarations in a assembly file without errors?

c++ - 将原始数据输出到扬声器

c++ - Visual Studio C++ 中的 DDALine

c++ - 在虚拟机之间分布单元测试

PHP如何在标题重定向到另一个页面之前回显警报

java - 在 Java 中包含 Perl

c++ - 从 cin 获取输入并将其存储在 char 变量中

sql - 如何将列名添加到由SQL输出语句创建的csv文件中?

c++ - 为什么在全局范围内使用 “extern int a”似乎不可行?

php - 关于 PHP include 语句的问题