c++ - 在 C++ 中,当你制作多个类时,你是否应该将它们分别放在它们自己的 .cpp/.h 对中?

标签 c++

<分区>

假设我有一个类似这样的程序

#include <iostream>
#include <algorithm>

class HelloWorlder
{
public: 
  HelloWorld();
  ~HelloWorld();
  void print_content() {std::cout << "Hello, world!"};
};

class StringReverser
{
public:
  Reverser();
  ~Reverser();
  void reverse_and_print(std::string & s) {std::reverse(s.begin(), s.end()); std::cout << s;}

};

int main()
{
    HelloWorlder HW;
    HW.print_content();

    StringReverser SR;
    SR.reverse_and_print("Jon Skeet");

    return 0;
}

然后我应该将它们分成文件 main.cppHelloWorlder.hHelloWorlder.cppStringReverser。 hStringReverser.cpp;还是只使用一个 main.cpp、一个 .h 和一个 .cpp?如果是前者,那么如果其中一个类使用另一个类,我该如何将文件链接在一起?例如,如果我将第二类更改为

class StringReverser
{
public:
  Reverser();
  ~Reverser();
  void reverse_and_print(std::string & s) {std::reverse(s.begin(), s.end()); std::cout << s;}
private:
  HelloWorlder h;
}

那我是否必须做类似的事情

StringReverser.cpp

#include "StringReverser.h"
#include "HelloWorlder.h"

class StringReverser
{
public:
  Reverser();
  ~Reverser();
  void reverse_and_print(std::string & s) {std::reverse(s.begin(), s.end()); std::cout << s;}
private:
  HelloWorlder h;
}

或者我还需要做其他事情吗?

最佳答案

这是约定俗成的;两种做法都被使用:每个类一个文件的小型 C++ 文件,或具有多个相关类和函数的大型 C++ 文件。

我不建议将 C++ 中的每个类放入其单独的源文件和头文件中(这几乎是 Java 所要求的,而不是 C++ 所要求的)。我相信一个类在概念上属于某个“模块”(通常一个“模块”包含几个相关的类和函数)。

所以我建议在同一个头文件(例如 foo.hh )中声明相同“模块”的相关类,并在相关(或相同)代码文件(例如一个 foo.cc 或多个foo-bar.cc & foo-clu.cc & foo-dee.cc ), 每个都是 #include -ing foo.hh

您通常希望避免使用非常短的 C++ 文件(以避免构建时间过长)。所以我更喜欢几千行的代码文件,几百行的头文件。在小型应用程序(例如少于 3 万行代码)中,我可能只有一个通用头文件。而一个“模块”(目前这只是一个设计,没有明确支持模块的 C++11 特性)通常由几个相关的类和函数组成。所以我发现一个源文件实现一个包含多个类的“模块”比几个小的源文件更具可读性和可维护性。

避免使用非常短的源代码文件(例如一百行代码)是有原因的。您的 C++ 程序将使用标准 C++ 模板 containers ,因此 #include - 直接或间接 - 几个标准 header ,如 <string><vector><map><set> 等......实际上,这些 header 可能带来数千行(编译器将解析)。例如,同时包含 <vector><map> 会在我的 GCC 4.9 上带来 41130 行。因此,仅包含这两个 header 的一百行源文件需要花费大量时间进行编译(并且您通常需要在 header 文件中包含标准容器)。因此,一个包含十个源文件(每个源文件几千行)的程序比包含数百个源文件(每个源文件几百行)的程序构建速度更快。查看使用 g++ -Wall -C -E 获得的代码的预处理形式!

C++ 的 future 版本可能有适当的模块(C++ 标准化委员会已经并将讨论这个问题,例如 n4047)。今天 C++11 没有它们,所以我引用了“模块”。一些语言(Go、Rust、Ocaml、Ada 等)已经有了合适的模块。而一个模块一般由几个相关的类、类型、函数、变量组成。

一些 C++ 编译器能够预编译头文件。但这是特定于编译器的。对于 g++,只有当你有一个通用头文件时它才能正常工作。参见 this answer

顺便说一句,您应该查看现有的 free software C++ 代码。一些项目有很多小文件,其他项目有较少但较大的文件。两种方法都用到了!

关于c++ - 在 C++ 中,当你制作多个类时,你是否应该将它们分别放在它们自己的 .cpp/.h 对中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26954620/

相关文章:

c++ - 如何将 std::promise 传递到线程中?通过 std::move 还是通过 std::shared_ptr?

c++ - QtVirtualKeyboard 使用平台 WebGL 卡住 QML 应用程序,但桌面工作正常。如何解冻或解决它?

c++ - 使用 std::enable_if<> 的模板特化

c++ - 使用 libpd 时如何处理不能被 64 整除的音频缓冲区大小?

c++ - QT MYSQL驱动构建, undefined reference `mysql_get_client_version@0'

c++ - 如何在我不想编辑的第 3 方代码中禁用来自 gcc 的未使用变量警告?

c++ - 在 Ubuntu 上为 vim 安装 clang_complete

c++ - GetDIBits 并使用 X、Y 遍历像素

c# - 原生进程调用C#进程可以使用哪些技术?

C++ 映射值作为列表,从列表中添加和删除元素