2

在我正在处理的一个项目中,我有一个相当大的模板类,我已经像这样实现了:

我有我的头文件

// MyBigClass.h
#ifndef MYBIGCLASS_H
#define MYBIGCLASS_H

template <typename T>
class MyBigClass {
   /* -- snip -- */
};

#include "MyBigClass.cpp"
#include "MyBigClass_iterator.cpp"
#include "MyBigClass_complicatedFunctionality_1.cpp"
#include "MyBigClass_complicatedFunctionality_2.cpp"

#endif

然后我所有的实现文件看起来基本上是这样的:

// MyBigClass_foobar.cpp

template <typename T>
void MyBigClass<T>::member_1(){
   /* -- snip -- */
}

template <typename T>
int MyBigClass<T>::member_2(int foo, T & bar){
   /* -- snip -- */
}

// etc, etc

main.cpp中,我只包括MyBigClass.h,一切正常,编译正常。我将实现拆分为多个文件的原因是因为我更喜欢处理三个或四个 200-400 行文件,而不是一个 1200 行文件。这些文件本身的组织结构相当合理,例如仅包含嵌套类的实现或一组相互关联的成员函数。

我的问题是,这件事已经完成了吗?前几天我把这个给别人看时,我得到了一个奇怪的反应,所以我想知道这是否是一种不好的做法,或者是否有更好、更常用的方法来完成这样的事情。

4

4 回答 4

5

通常不包含文件是惯例cpp(这样做时存在有限和奇异的情况),这可能是您看起来怪异的原因。

通常这种分离是通过将实现移动到一个.impl甚至一个.h文件而不是一个文件来完成的cpp

不,分离模板的实现并将文件包含在标头中没有任何问题。

于 2012-07-19T20:53:56.903 回答
4

所以... include.cpp是一种不好的做法,但是是什么阻止您使用头文件而不是.cpp? 例如提升使用.ipp文件...

于 2012-07-19T20:54:44.677 回答
2

在处理过包含数千个或更多文件的 C/C++ 项目之后,这是我通常观察到的做法:

  1. 将类定义保留在头文件中。不要在头文件中添加任何实现。内联函数和模板除外。最后我会谈到这一点。
  2. 将所有函数和方法实现保存在 .c 或 .cpp 文件中。

这样做有根本原因。

  1. .h 文件充当任何人使用您在代码中实现的类/函数/和其他数据结构和 API 的参考点。任何不知道类结构的人都会首先参考 .h。
  2. 您可以分发仅显示 .h 文件的库,而不显示您的实际实现。通常他们会提出外部 API(同样在 .h 文件中),这些 API 是库中任何代码的唯一入口点,如果希望共享代码,第三方可以使用这些 API。
  3. 如果您在多个位置包含 .c 或 .cpp 文件 - 在编译过程中您不会看到任何错误 - 但链接器将摆脱抱怨重复符号的问题。由于它包含您包含的 .c/.cpp 文件的所有这些功能/方法部分的多个副本。

例外

  1. 内联函数实现需要存在于 .h 文件中才能生效。在某些情况下,编译器可能会自动决定一段代码可以内联 - 但在某些情况下,它需要存在 inline 关键字。注意:我在这里只谈论后者。只有当它看到 inline 关键字时,编译器才会内联任何函数。换句话说,如果 .cpp 具有以下代码:

    A类;A.my_inline_method();

如果在编译此 cpp 文件时 my_inline_method() 作为内联函数对编译器不可见,则它不会内联此函数。

  1. 在编译方面,模板类似于内联方法——当模板的代码需要由编译器在使用它的 .cpp 中生成时——它需要知道该模板的整个实现。由于模板代码生成是编译时而不是运行时。

我已经提到了这背后更常见的哲学。如果我错过了,请随时编辑此答案以添加更多内容。

此处有关模板内容的更多信息:为什么模板只能在头文件中实现?

编辑:根据@Forever 的评论进行更改以避免歧义。

于 2012-07-19T21:09:32.810 回答
1

我正在回答我自己的问题,以补充一点,模板实现的标准扩展似乎是.tcc. 它被 github 的语法 highlighter 识别gcc,并且在手册页中也提到:

C++ 源文件通常使用后缀.C, .cc, .cpp, .CPP, .c++, .cp, 或.cxx;之一。C++ 头文件经常使用.hh, .hpp, .H, or (用于共享模板代码).tcc

如果我误解了.tcc扩展程序的预期用途,请告诉我,我将删除此答案!

于 2012-07-27T02:26:08.077 回答