【问题标题】:Any disadvantage if only using cpp files without separate header files?如果只使用没有单独头文件的 cpp 文件有什么缺点吗?
【发布时间】:2010-12-28 06:00:37
【问题描述】:

我找到了一些线程来解释为什么 C++ 将 .cpp 和 .h 文件分开(例如 here)。如果我将它们分开,我很想知道它是否会导致任何问题。我不想共享目标文件,那么在一个小项目上分离有什么好处?如果它只是减慢编译时间,我认为这没什么大不了的。我想用 C++ 重新实现一个 Java 程序,所以对我来说,将一个类只保存在一个文件中似乎要容易得多。示例:

// Hello.cpp
#ifndef HELLO_20091218
#define HELLO_20091218

#include <iostream>
#include "Utils.cpp"

class Hello
{
public:
    void start()
    {
        std::cout << Utils::nrand(100) << "\n";
        // Utils and all other classes are written in a similar way
    }
};

#endif

有一件事让我很烦恼。 “在类中定义一个成员函数要求实现扩展对它的内联调用。”因此,如果我这样做,所有内容都会被隐式标记为内联。它会导致更大的可执行文件或任何其他缺点吗?

【问题讨论】:

标签: c++ header-files


【解决方案1】:

在 C 和 C++ 中,最小的编译单元是文件。如果您只是不使用头文件并将所有内容都包含在“主”文件中,那么每次您更改某些内容时,您的整个程序都必须重新编译。对于较大的应用程序,这可能是分离标头和实现的一个很好的论据。此外,如果您的应用程序的另一部分将存在于另一个二进制可执行文件中,并且您不想重用类,则使用头文件是安全的,但如果没有它们,您将获得大量开销。

如果你不关心那些事情(你会后悔的。)你不需要单独的头文件。

关于内联:编译器无论如何都会内联很多函数(有时甚至是整个类),即使你没有要求它这样做。内联通常对性能有好处。有一些极端情况(较大的可执行文件可能会导致执行速度变慢),但这些情况相当不寻常。

【讨论】:

    【解决方案2】:

    这确实是两个问题。

    现在,您在上面显示为“Hello.cpp”的内容看起来像一个标头,并带有一个包含保护。编译器并不真正关心你给你的头文件起什么名字,但是包含一个 .cpp 文件会让任何查看你的代码的人(充其量)感到困惑。如果您自己编译它,则包含保护(至少)应该可能会消失 - 虽然它不会造成真正的问题,但它充其量是毫无意义和令人困惑的。

    是的,您在类定义中定义的成员函数是隐式内联的。但这并不意味着编译器需要为它们生成内联代码。这基本上只是给编译器的一个提示,大多数编译器自己决定是否生成内联代码,主要基于函数包含的内容,而不是定义的位置。

    【讨论】:

    • 另见#include "Utils.cpp",这绝对表明是这种情况。
    • 它不仅仅是一个标题,因为它还包含函数的定义。我的想法是定义一个类中的所有方法(例如在 Java 中)。
    • 您可以这样做,但标准做法是调用文件“Hello.h”,而不是“Hello.cpp”。如果您从其他文件中包含它,那么它就是一个标题,无论它定义什么。调用文件“*.cpp”会告诉其他人您要将其编译为“顶级”源文件。
    • @Steve Jessop:谢谢,我不确定在这种情况下使用哪个扩展。
    【解决方案3】:

    头文件的目的是封装应用程序视为API的特定功能。

    在很多情况下,对应的源文件都在一个单独的库文件中,或者至少是一个独立的包中。将源代码(作为单独的文件)直接组合到一个项目中是方便的,并且通常有助于开发,而不是构建一个库并将其链接。

    packagelibraryAPI 等词充斥着大量不同的技术含义,这证明了开发人员对此类的重要性安排。

    如果您认为自己编写的类将来可以重用,最好将其拆分为单独的 .cpp.h 文件,以便在另一个项目中轻松引用它。至于编译速度的损失,请考虑长期收益与成本。 (而且编译器和硬件每年都在变得更快。)

    【讨论】:

      【解决方案4】:

      “在罗马做罗马人做的事”

      您被骗以为可以像使用 Java 一样选择使用 C++。尽管这在技术上是正确的,但您打破了一些非常严格的约定,这些约定是有原因的。您可以在不调用 delete 的情况下轻松开始使用 new ,因为“这没什么大不了的”、“您的程序很小”或“操作系统将在您的程序关闭后回收所有内存”,但这并不意味着您应该这样做。我同意 C++ 比 Java 更复杂,这可能是一个真正的痛苦,但这是你必须处理的事情。这是每个 C++ 开发人员迟早都会接受的。

      【讨论】:

        猜你喜欢
        • 2020-09-27
        • 2011-03-11
        • 1970-01-01
        • 2010-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多