在头文件中定义模板并在派生类中的cpp文件中定义

时间:2012-10-18 17:59:11

标签: c++

  

可能重复:
  Why should the implementation and the declaration of a template class be in the same header file?

我正在尝试在头文件中定义模板,并在cpp文件中定义它,并且模板应该在派生类中定义。所以这就是我得到的:

标题文件:

#ifndef  ........
#define .....
 template <class mytypename>
 class abcBaseClass:public abcDerivedClass{
 public:
     mytypename getvalue(char*)
};
#endif


源文件:

mytypename abcDerivedClass<mytypename>::getvalue(char* name){

}

我只是想知道这是否是正确的做法?。

这就是我想要实现的目标......我想打电话的最后方式是

double x = a->getvalue<double>(char)

3 个答案:

答案 0 :(得分:3)

已经多次询问类似的问题。

但无论如何......

首先,您犯了一些语法错误。

而不是

#ifndef  ........
#define .....
 template <class typename>
 class abcBaseClass:public abcDerivedClass{
 public:
     typename getvalue(char*);
};
#endif

它应该是这样的。

#ifndef  ........
#define .....
 template <typename T>
 class abcBaseClass:public abcDerivedClass{
 public:
     T getvalue(char*);
};
// Definition follow in this file!
// For reasons or work-arounds, read below.
#endif

此外,模板声明和定义都应该放在同一个文件中。 一个例外是当您将模板实例化为模板定义所在的源文件中的某种类型时。

像这样。

#include "this_template.h"

template <typename T>
// all sorts of definitions...

// Explicit instantiate this template!!!!
template class abcBaseClass<Your_Type_Goes_Here>;

注意,这种方法的一个根本缺陷是,您只能在程序中的其他位置使用您在此源文件中显式实例化的类型。尝试使用其他类型实例化此模板将导致链接器抱怨无法找到匹配的定义。

如果你坚持模板都是通用的,并且在其他地方有模板类的定义。 您可以将定义放入另一个头文件中,只需将其称为this_template_impl.h,并在this_template.h中包含this_template_impl.h

然后,在源文件中,而不是#include "this_template.h",而是编写#include "this_template_impl.h

答案 1 :(得分:1)

您可以将定义放在.cpp文件中,但这样做更麻烦,而不是通常的模板方式。

在.cpp中需要一些额外的代码来说服编译器生成填充了必要模板参数的函数。一种方法是以某种方式使用函数:

mytypename abcDerivedClass<mytypename>::getvalue(char* name){

}

void dummy()
{
    abcDerivedClass<double> temp;
    temp->getvalue(NULL);
}

没有必要实际调用虚函数,只需将其放在那里(在模板定义之后)就足够了。

我确信还有另一种显式实例化模板的方法,但由于我不这样做,我永远不会记得。

答案 2 :(得分:0)

不,这不是正确的方法:

应该这样做:

#ifndef  ........
#define .....
 template <class T>
 class abcBaseClass:public abcDerivedClass{
 public:
     T getvalue(char*)
};

#endif

并在.cpp文件中:     模板     T abcBaseClass :: getvalue(char * ch){     }

您的代码不正确的原因是因为typename是C ++关键字。并且必须在编译期间抛出错误

您也可以使用:

#ifndef  ........
#define .....
 template <typename T>
 class abcBaseClass:public abcDerivedClass{
 public:
     T getvalue(char*)
};
#endif

并在C ++文件中:

template<class T>
T abcBaseClass<T>::getvalue(char * ch){
}