2012-07-19 64 views
2

在一个项目中我的工作,我有我已经这样实行了相当大的模板类:#include'.cpp模板实现文件是一种不好的做法吗?

我有我的头文件

// 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行文件。这些文件本身在逻辑上是相当组织的,例如只包含嵌套类的实现或者一组相关的成员函数。

我的问题是,这是做什么?当我前几天向某人展示这件事时,我得到了一个奇怪的反应,所以我想知道这是否是一种不好的做法,或者是否有更好,更普通的方式来完成这样的事情。

回答

5

这是约定一般不包括cpp文件(这是有限和异国情况下完成时),这可能是你得到奇怪的外观的原因。

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

不,没有什么错分开模板的实现并在头中包含文件。

4

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

+0

感谢您的回答,'.ipp'好像它是去 – 2012-07-19 21:09:44

2

已经有一千多个文件在C/C++项目的经验,这是我观察到一般的做法:

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

有这样做的根本原因。

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

例外

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

    class A; A.my_inline_method();

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

  1. 模板与编译时的内联方法类似 - 当模板的代码需要由编译器在使用它的.cpp中生成时 - 它需要知道该模板的整个实施。由于模板代码生成是编译时和非运行时。

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

更多信息:Why can templates only be implemented in the header file?

编辑:根据@永远的评论,以避免歧义所做的更改。

+0

联函数的实现需要存在.h文件中,否则他们将不会被到处内联的好办法。编译器只有在看到inline关键字时才会内联任何函数。换句话说,如果.cpp具有以下代码片段: 否...内联关键字只能在推荐连接时通过内联向编译器+函数内联。 – ForEveR 2012-07-19 21:16:12

+0

你会在我的情况下通常会期待什么?包含'.cpp'文件,或其他扩展名,如'.ipp'或'.impl'像其他人所说的那样? – 2012-07-19 21:31:18

+0

查看有关在.cpp文件中使用模板实现的可能问题的链接:http:// stackoverflow。com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file如果你认为你不会遇到这种情况 - 只保留当前的实现,如果不重构它。 – Tuxdude 2012-07-19 21:35:17

1

我回答我自己的问题,补充说模板实现的标准扩展似乎是.tcc。这是recognized by github's syntax highlighter,并且在gcc手册页也提到:

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

如果我误解了.tcc扩展名的用意,请让我知道,我会删除这个答案!

+0

感谢您的回答;它给出'.ipp'或'.impl'的替代方案,在我的情况下,它不完全适合使用'.cc'作为源文件的项目。 – congusbongus 2013-03-06 23:35:40

相关问题