我应该在C ++中分离cpp和h文件吗?

时间:2014-12-13 07:57:54

标签: c++ templates makefile linker

我在C ++程序中调用了一个模板:

const matrix::CMatrix<double> M1(3,3,{{5.0,0.0,2.0},{1.0,1.0,3.0},{6.0,7.0,7.0}});

我遇到了这样的链接器错误:

tests.h:15: undefined reference to `matrix::CMatrix<double>::CMatrix(int, int, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >)'
在大规模搜索之后,我终于意识到这是因为我已经分离了我的h和cpp文件而且template不能容忍它。在C中,建议分离c和h文件并使用Makefile。但根据c ++中的这些问题,仍然建议将cpp和h文件分开?在h文件和cpp文件中的一些其他函数中实现一些模板并不是一种干净的方法。我该怎么办?

修改

matrix.h

template<typename T>
class CMatrix
{
.....

matrix.cpp

implementation of CMatrix

的main.cpp

defining M1

3 个答案:

答案 0 :(得分:1)

如果要在多个文件中使用模板,请将模板放在头文件中,以便将其包含在其他位置。如果您只需要文件中的模板,那么将其放在cpp中。

答案 1 :(得分:1)

是的,您应该将CPP与.h文件分开 这不仅仅是一个建议。

.cpp文件被编译成编译单元,这意味着每个.cpp文件都被编译成.obj文件,包含它拥有的所有代码,以及它包含的所有代码。

因此,如果您在.h文件中包含许多.cpp文件中的某些代码,则会多次编译。

现在,当你有多个项目和图书馆时,这个事实会变得很丑陋。

无论如何,模板是一个不同的问题 模板calsses在实例化之前不会被编译(直到你使用它们为止) 然后编译器为正确的类型创建所需的代码 它不仅仅是在编译器第一次看到模板化代码时编译(比如“常规代码”)

因此,您需要在头文件中包含该模板化代码,因此编译器会在使用它的每个编译单元(.cpp)文件中“看到”它。 因此,编译器可以在需要的地方创建正确的代码。

答案 2 :(得分:0)

如果模板化方法是私有的,您可以而且应该将定义(方法体)放在.cpp文件中。如果它们是公共的,它们只需要在.hpp文件中。

将所有内容放在标题中是一个问题:如果您绘制所有文件的依赖关系树,并将main.cpp作为根节点,那么只有在没有依赖关系向上的情况下它才有效。这当然是一个伟大而简单的设计,但在实践中,你经常需要一些向后引用(可能是任何东西,比如将某个类作为参数或将某个类作为成员的方法)。那时你可能会得到很多“不完整的类”编译器错误......