C ++使用模板时分离声明和类定义的最佳方法是什么

时间:2015-04-01 18:33:45

标签: c++

我在这个主题上搜索了很多。我遇到了三种方法。假设我们有3个文件,main.cpp,声明头文件和definiton cpp文件。    第一种方法建议在cpp文件中创建临时对象。    第二种方法建议在主文件中包含cpp和头文件。   第三种方法建议在头文件中包含cpp文件。

现在的问题是:哪一个是最好的方法?通过说得最好,我的意思是兼具良好的性能和良好的代码样式。 还有其他更好的方法吗?

2 个答案:

答案 0 :(得分:1)

应始终在类体内定义模板。这是最受欢迎的解决方案,因为它简单明了,可以避免大量不必要的打字。

考虑以下课程:

template <CharEncoding Encoding>
class UnicodeConverter
{
protected:
    template <typename Input_char_type, typename Output_char_type>
    class InternalHelper
    {
    public:
        void function_a()
        {
            //do something
        }
    };

    //...
};

现在想象一下,如果你想要一个单独的定义文件,你需要写什么:

template <CharEncoding Encoding>
template <typename Input_char_type, typename Output_char_type>
void UnicodeConverter<Encoding>::InternalHelper<Input_char_type, Output_char_type>::function_a()
{
  //do something
}

这绝对不是很好也不可读,你不同意吗?

在某些情况下,定义必须分开(例如,两个模板,彼此依赖),但在大多数情况下:避免它!

将实施放在单独的.cpp文件中的规则通常不适用于模板。 C ++标准库也主要是基于头的,因为它广泛使用模板来处理所有事情。

另外,请注意,我的示例代码是一个真实的示例,取自真实的应用程序(稍加修改)。并且想象一下,这不是我在这个项目中最复杂的模板。

答案 1 :(得分:1)

  

第一种方法建议在cpp文件中创建一个临时对象。

  

第二种方法建议在主文件中包含cpp和头文件。

大多数编译器不支持以这种方式拆分模板代码。它需要使用外部模板定义,但尚未得到广泛支持。大多数编译器都需要在同一个翻译单元中声明和定义模板。这带给我们第三个选择...

  

第三种方法建议在头文件中包含cpp文件。

这是大多数人采用的方法,如果他们甚至根据定义将模板声明分开(参见下面的第4个选项)。但是,通常使用.icc文件扩展名而不是.cpp命名定义文件,以使此区别更清晰。例如:

myfile.h:

template<typename T>
class TMyClass
{
public:
    void doSomething(T value);
};

#include "myfile.icc"

myfile.icc:

template<typename T> void TMyClass<T>::doSomething(T value)
{
    //...
}

这将我们带到第4个选项 - 根本不拆分代码,而是实现内联。这是编写模板的更常用方法。例如:

myfile.h:

template<typename T>
class TMyClass
{
public:
    void doSomething(T value)
    {
        //...
    }
};