为什么不使用cpp文件包含类?

sup*_*oda 5 c++

这个问题并不是重复" 为什么我不应该包含cpp文件而是使用标题? "而是更多的实践问题.

为了最好地构思这个问题,让我解释一下 在编写课程时,如果不是更多,它可以快速增长到几百行.出于可读性目的,我想基于每个方法将一个类分成单个文件.为了清楚起见,我并不是建议将整个项目变成一组包含,因为上面列出的帖子中提到的原因,而是将一个类分解为包含在他们自己的文件中的组件.

以下代码片段说明了我的意思

main.cpp中

#include <iostream>
#include "helloClass.h"
using namespace std;

int main()
 {
         hello a;
         cout<<a.out();
         cin.get();//just to pause execution
 }
Run Code Online (Sandbox Code Playgroud)

helloClass.h

#ifndef HELLOCLASS_H
#define HELLOCLASS_H
#include <string>
class hello
{
std::string  message;

public:
std::string out();
hello();
};

#endif
Run Code Online (Sandbox Code Playgroud)

helloClassMain.cpp

#include "helloClass.h"     
using namespace std;        
hello::hello()              
{                           
   message = "Hello World!";   
};                          

#include "helloClassOut.cpp"
Run Code Online (Sandbox Code Playgroud)

helloClassOut.cpp

string hello::out()
{                  
return message;    
}                  
Run Code Online (Sandbox Code Playgroud)

这将编译正常并按预期执行.当发生错误时我发现了一个额外的好处,因为编译器不仅会告诉你什么行,还会告诉你错误所在的文件.例如,我用未声明的变量编译它

$ c++ main.cpp helloClassMain.cpp -o hello
In file included from helloClassMain.cpp:8:0:
helloClassOut.cpp: In member function ‘std::string hello::out()’:
helloClassOut.cpp:3:1: error: ‘fail’ was not declared in this scope
fail="test";
Run Code Online (Sandbox Code Playgroud)

我发现这至少可以说是有用的,它允许我将文件helloClassMain.cpp视为hello类的入口点及其所有方法和属性.

我知道这最终与在同一个文件中写出类的原因相同,因为编译器的工作原理.这只是一个能够更容易阅读,故障排除等问题.

最后问题.

  1. 这是不好的做法吗?
  2. 对于那些在项目上与我合作的人来说,它会变得多么地狱吗?
  3. 我缺少一个核心概念吗?我相信我不是第一个考虑这个解决方案的人.
  4. 我是否更多地询问了偏好问题而不是最佳做法?
  5. 最后是否有一个我所描述的名称而不是坏的名称?

Cor*_*lks 4

  1. 这是不好的做法吗?

通常,是的。我唯一能想到这可能是可取的,如果您有一些在不同系统(即 Windows 和 Linux)上以不同方式实现的方法。如果有特定于系统的方法,您可能会这样做。但除此之外,它会让人皱眉。

  1. 这会让那些与我合作项目的人感到痛苦吗?

是的,因为:

  • 智能感知不适用于您的流氓文件(因为它们没有#include所需的定义)。
  • 您正在创建经过#include编译而不是编译的 .cpp 文件。这是误导。
  • #include将 .cpp 文件插入另一个 .cpp 文件是解决命名空间冲突的好方法。也许一个 .cpp 文件具有与另一个 .cpp 的全局静态帮助器冲突的全局静态帮助器函数。也许您using namespace std;在一个文件中弄乱了另一个文件。
  • 如果您要编译 .cpp 文件而不是#include它们,则可以利用并行编译。使用起来#include会慢很多,因为如果你稍微改变一个方法,那么所有的方法都必须重新处理和编译。相反,如果您单独编译每个 .cpp(这是正常的事情),则更改一个 .cpp 文件意味着只需要重新处理和重新编译该文件。
  1. 我在这里缺少一个核心概念吗?我确信我不是第一个考虑这个解决方案的人。

如果没有更具体的示例,您可能会错过单一责任原则。你的班级可能太大并且做的事情太多。

此外,类代表具有状态的对象;将状态分布在多个文件中使得从概念上理解整个状态变得更加困难(如果全部位于同一个文件中,它可以帮助我查看和理解整个对象的状态)。我敢打赌,您将会遇到更多错误,因为对象的状态并不像您想象的那样一致。

  1. 我是否更多地询问了偏好而不是最佳实践?

两者兼而有之。不过现在我们正在获取元数据。

  1. 除了“坏”之外,我所描述的东西最后还有一个名字吗?

也许有一个技术名称,但我倾向于毒圣杯。

  • @JamesKanze:说实话,我从未见过任何项目这样做。我怀疑这是否是公认的“最佳实践”。 (2认同)