在我正在进行的项目中,我有一个相当大的模板化课程,我已经实现了这样:
我有我的头文件
// 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行文件。文件本身在逻辑上是相当有条理的,仅包含嵌套类的实现或一组相互关联的成员函数。
我的问题是,这件事情已经完成了吗?前几天当我向某人展示时,我得到了一个奇怪的反应,所以我想知道这是不是一种不好的做法,或者是否有一种更好,更常用的方式来完成这样的事情。
答案 0 :(得分:5)
通常不包含cpp
文件(这种情况有限且充满异国情调),这可能是你得到奇怪外观的原因。
通常,通过将实现移至.impl
甚至.h
文件而非cpp
文件来完成此分离。
不,分离模板的实现并在标题中包含文件没有任何问题。
答案 1 :(得分:4)
所以...包含.cpp
是一种不好的做法,但是什么阻止您使用头文件而不是.cpp
?例如,提升使用.ipp
文件......
答案 2 :(得分:2)
参与了有数千个或更多文件的C / C ++项目,这是我一般观察到的做法:
有这样做的基本原因。
<强>例外强>
内联函数实现需要在.h文件中存在才能生效。在某些情况下,编译器可能会自动决定是否可以内联一段代码 - 但在某些情况下,它需要存在inline关键字。 注意:我在这里只讨论后者。编译器只有在看到内联关键字时才会内联任何函数。换句话说,如果.cpp具有以下代码:
A级; A.my_inline_method();
如果编译此cpp文件时编译器看不到my_inline_method()为内联函数,则不会内联此函数。
我已经提到了这背后更为常见的哲学。如果我错过了,请随意编辑此答案以添加更多答案。
有关模板资料的更多信息:Why can templates only be implemented in the header file?
编辑:根据@ Forever的评论进行更改以避免歧义。
答案 3 :(得分:1)
我正在回答我自己的问题,补充说模板实现的某种标准扩展似乎是.tcc
。它是recognized by github's syntax highlighter,也在gcc
手册页中提到:
C ++源文件通常使用其中一个后缀
.C
,.cc
,.cpp
,.CPP
,.c++
,.cp
或{ {1}}; C ++标头文件通常使用.cxx
,.hh
,.hpp
,或(对于共享模板代码).H
;
如果我误解了.tcc
扩展名的预期用途,请告诉我,我会删除此答案!