好,所以我没有问题,但是有一个问题: 使用c ++时,您可以将类转移到另一个文件并包括它,而无需创建标头,如下所示:
foo.cpp:
#include <iostream>
using namespace std;
class foo
{
public:
string str;
foo(string inStr)
{
str = inStr;
}
void print()
{
cout<<str<<endl;
}
};
main.cpp:
#include "foo.cpp"
using namespace std;
int main()
{
foo Foo("That's a string");
Foo.print();
return 0;
}
所以问题是:这种方法是否比使用头文件还要糟糕?它更容易使用,也更干净,但是会更慢,是否会引起更多错误? 我已经搜索该主题很长时间了,但是考虑到这个选项,我在互联网上还没有看到一个主题...
答案 0 :(得分:2)
命名文件.cpp
或.hpp
(或.c
/ .h
)之间没有语义上的区别。
人会对#include "foo.cpp"
感到惊讶,编译器不在乎
答案 1 :(得分:2)
您仍然创建了“头文件”,但是给了它扩展名“ .cpp”。文件扩展名是给程序员的,编译器不在乎。
从编译器的角度来看,您的示例与
之间没有区别foo.h:
#include <iostream>
using namespace std;
class foo
{
//...
};
main.cpp:
#include "foo.h"
using namespace std;
int main()
{
// ...
}
答案 2 :(得分:1)
“头文件”只是您在头文件中包含的文件,即另一个文件的头文件(从技术上讲,头文件不必在头文件中,有时也不必,但通常是头文件,因此是名称)
您仅创建了一个名为foo.cpp
的头文件。
命名通常用于源文件的扩展名头文件不是一个好主意。某些IDE和其他工具可能会错误地认为您的标头是源文件,因此尝试像编译头文件一样进行编译,否则就浪费了资源。
更不用说它可能引起您的同事的困惑。源文件可能具有C ++标准只允许定义一次的定义(请参阅一个定义规则odr),因为其他文件中未包含源文件。如果您将标头命名为源文件,那么有人可能会认为无法在其中具有odr定义。
答案 3 :(得分:0)
所以问题是:这种方法是否比使用头文件还要糟糕?
您可以考虑回顾“ C ++翻译单元”是什么的中心思想。
在您的示例中,预处理器的工作就像将foo.cpp的副本插入到main.cpp的内部副本中一样。预处理器执行此操作,而不执行编译器。
所以...当编译器是单独的文件时,编译器从不会看到您的代码。正是这个单一的,串联的“翻译单元”被提交给编译器。 .hh和.cc中没有魔术,只是它们满足了您的同事(或老板)的期望。
现在考虑一下您的问题……翻译单元既不是您的源文件,也不是您的系统的任何包含文件,但它是由预处理器组合在一起的一个文本流,一件事。那么它会好还是坏?
更容易,更干净
可以。我在“私人”编码工作中经常采用这种“不同”方法。
当我快速评估了阶乘使用gmpxx.h(mpz_class)时,确实确实采用了这些快捷方式,并且不需要.hpp文件即可正确创建我的编译单元。仅供参考-12345的阶乘是超过45,000字节。读字符也毫无意义。
在“更正式”的工作(工作,合作等)下,我总是使用头文件,并单独进行编译,并构建对应用程序有用的函数库,作为应做事情的一部分。特别是如果我可能共享此代码或为公司档案做贡献。我有太多充分的理由来描述为什么我建议您学习这些问题。
但是它会更慢,会引起更多错误吗?
我认为不是。我觉得不是。有一个编译单元,连接各个部分必须正确,但是我认为这并不困难。
我已经搜索该主题很长时间了,但是没有看到一个 互联网上的话题,甚至考虑到这个选项...
我不确定我是否曾经看过它。我已经获得了信息。通常认为分开的编译和库开发可以节省开发时间。 (时间就是金钱,对吗?)
此外,还有一个库和头文件,这些文件是如何包装成功供他人使用的,以及如何提高团队价值的方法。
答案 4 :(得分:0)
如果您曾经构建过一个较大的项目,那么两个主要区别将对您显而易见:
如果您将代码作为库交付给他人,则必须给他们 all 所有代码-所有IP-而不是仅向公开类的标头加上已编译的库
如果在任何文件中更改一个字母,则将需要重新编译所有内容。一旦大型项目的编译时间达到数分钟,您将失去很多生产力。
否则,它当然可以工作,并且结果是相同的。