2

我找到了一些线程来解释为什么 C++ 将 .cpp 和 .h 文件分开(例如这里)。如果我将它们分开,我很想知道它是否会导致任何问题。我不想共享目标文件,那么在一个小项目上分离有什么好处?如果它只是减慢编译时间,我认为这没什么大不了的。我想用 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

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

4

4 回答 4

3

这真的是两个问题。

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

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

于 2009-12-19T02:04:26.690 回答
3

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

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

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

于 2009-12-19T02:11:50.327 回答
2

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

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

诸如packagelibraryAPI之类的词充满了替代的技术含义,这证明了开发人员对这种安排的重要性。

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

于 2009-12-19T02:10:01.017 回答
1

“在罗马做到入乡随俗”

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

于 2009-12-19T09:10:57.640 回答