【问题标题】:Should I separate cpp and h file in C++?我应该在 C++ 中分离 cpp 和 h 文件吗?
【发布时间】:2014-12-13 07:57:53
【问题描述】:

我在我的 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 文件中实现一些其他功能不是干净的方法。我该怎么办?

编辑:

矩阵.h

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

矩阵.cpp

implementation of CMatrix

main.cpp

defining M1

【问题讨论】:

  • “分离”是什么意思?您的模板在哪里声明(在 .cpp 或 .h 中)以及在哪里使用?

标签: c++ templates makefile linker


【解决方案1】:

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

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

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

现在,当您拥有多个项目和库时,这一事实可能会变得很糟糕。

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

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

【讨论】:

    【解决方案2】:

    如果您想在多个文件中使用模板,请将模板放在头文件中,以便您可以将其包含在其他地方。如果您只需要文件中的模板,请将其放入 cpp。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多