0

C++ 是我学习的第一门语言,因此将源代码划分为 .h 和 .cpp 文件似乎很明显 - 但是在学习了 C# 和 Java 之后,它们现在在我看来非常笨拙。它们可能在 60 年代很有用,甚至可能在 80 年代仍然有用,但在现代工具时代,例如带有部分折叠的 IDE 和文档生成器,它们似乎已经过时了。

无论如何,我的问题是:是否有一种工具可以使这两种文件的存在对程序员透明?例如,让编码人员看似在头文件中写入方法的定义,但实际上将其保存到 .cpp 文件中?

(我知道可以尝试仅在头文件中编写 C++ 程序,但 AFAIK 这不是最佳实践,使程序构建时间更长,并且几乎不可能让两个类相互引用。)

4

4 回答 4

4

我在问题、评论和对另一个答案的评论中看到的讨论似乎集中在组件的文本表示上。从纯文本的角度来看,完全删除标题是有意义的。

另一方面,头文件和 cpp 文件的分离还有第二个层次,即将接口与实现分离,并在这样做时从接口中删除实现细节。

这以不同的方式发生,在最简单的层面上,您实现特定功能的方式与组件的用户无关[*]。在许多情况下,您可以在 .cpp 文件中拥有更多类型和函数,这些类型和函数仅用作实现细节。此外,如果您决定直接或通过依赖另一个库来实现特定功能,这是实现的细节,不应泄露给您的用户。

在自动管理文件分离的工具中实现这种分离可能会也可能不会容易,并且不能由那些喜欢使用仅标头库的人来完成。

你们中的一些人声称不必去定义没有意义,并且希望完全查看代码,我看到的是可以灵活地决定组件的哪些部分是用户不应该知道的细节。在许多 IDE(甚至在 vim 中)中,只有一个按键组合可以将您从一个键带到另一个。在 IDE 中,您可以重构函数的签名并让 IDE 将更改应用到标头和实现(有时甚至应用到使用)...

如果您要让一个工具提供标头和实现的统一视图,那么让该工具了解您正在编写的代码的哪些部分是接口或实现的一部分以及决策可能会困难得多该工具可能会对生成的程序产生影响。

单独编译模型有其缺点,但也有优点,我觉得这里进行的讨论只是触及更深层次的设计决策的表面。

[*] 似乎有不少人认为每个类都应该有自己的头文件和 .cpp 文件,我不同意,每个头文件代表一个组件,可能是单个类,也可能是多个类和自由函数的分离文件中的代码是设计的一部分,并且在单个组件中,您可能有一个或多个公共类型以及可能没有或多个内部类型。

于 2012-04-06T16:19:07.940 回答
3

我不知道有什么可以使源/标头的划分完全透明。

但是,我确实知道一些使它更容易处理的方法。例如,Visual Assist X 将让您将整个类写入头文件,然后选择成员函数,并将它们移动到源文件(即 .cpp 文件)。

这不是完全治愈(无论如何),但无论如何它可以/确实使它们更容易忍受。

就个人而言,我认为完全摆脱文件会很有趣,而是直接使用数据库之类的东西——即,你有一个函数数据库,其中该函数的源代码是一列,目标代码是另一列,内部关于如何使用它的编译器信息还有一个,等等。这也将使集成版本控制变得非常简单(基本上只是一个存储的事务日志)。

于 2012-04-06T16:19:19.480 回答
1

一方面,我喜欢 C++ 中的头文件,因为它们可以充当某种“目录”,让您快速了解一个类。当然,这是假设您保持标题简短,并将大多数功能的实现放入 .cpp 中。

此外,您可以获得 Visual Studio 的插件,这些插件会将成员函数的实现从标头移动到 .cpp 中。再加上 Visual Studio 中的“转到定义”和“转到声明”命令,标题对于浏览大型代码库非常有帮助。

于 2012-04-06T15:35:13.350 回答
0

头文件是当前 C++ 编译模型的基础。我认为如果不将程序员直接暴露于 header/cpp 拆分,有些事情会有点难以表达。例如,在某些情况下,两者之间存在显着差异:

// header
class Foo {
    Foo() = default;
}

// header
class Foo {
    Foo();
};

// cpp
Foo::Foo() = default;

尽管如此,我认为考虑改进编译模型或使其更容易处理是值得的。

例如,我可以想象一个“代码气泡”风格的 IDE,程序员在代码气泡中编写定义,然后将气泡组合成翻译单元。程序员会将定义标记为“已导出”,以使它们可用于其他 TU,并且对于每个 TU,他会选择从​​其他单元导出的项目以进行导入。IDE 一直在维护它自己的程序代码气泡表示,当您构建它时,它会根据需要生成传递给编译器、创建前向声明等所需的实际 cpp 文件。cpp 文件只是一个中间构建产品。

虽然会有像我上面展示的那样的微妙之处,但我不确定我描述的 IDE 将如何处理这个问题。

于 2012-04-06T17:58:38.180 回答