【发布时间】:2011-07-27 08:43:10
【问题描述】:
有一个基类:
template<class T_CLASS>
class TBase
{
protected:
static CSomeClass m_objSomeClass;
public:
inline void Set(CSomeClass f_objSomeClass) { m_objSomeClass = f_objSomeClass; }
};
还有一些子类都有自己的静态成员m_objSomeClass。我尝试通过模板化基类来做到这一点。
class CSub1 : public TBase<CSub1>
{
//...
};
class CSub2 : public TBase<CSub2>
{
//...
};
这个的定义是什么样的?甚至可能吗?我尝试了一些......但没有奏效:
template<class T_CLASS>
CSomeClass TBase<T_CLASS>::m_objSomeClass;
//In fact the next one worked in Visual Studio;
// but not in with the armcc where I need it.
CSomeClass TBase<CSub1>::m_objSomeClass;
CSomeClass TBase<CSub2>::m_objSomeClass;
有什么建议吗?谢谢,米尔科
【问题讨论】:
-
第一种方法应该有效:
template <typename T> CSomeClass TBase<T>::m_objSomeClass;,所以一定有一些你没有在代码中显示的东西。CSomeClass是否依赖于类型参数? -
我将定义移动到另一个源文件,最后它正在正确编译和链接......我仍然不知道之前出了什么问题。
CSomeClass在A.hpp中,Base和Sub类在B.hpp中,其中包括A.hpp,定义在B.cpp中。无论如何...感谢您的帮助! -
定义必须可访问在哪里使用该字段。这是一个 templated 定义,如果您在 cpp 文件中提供它,那么编译器将不会实例化静态成员
-
@David Rodríguez,您能详细解释一下吗?现在定义在 D.cpp 中 - 因此它在 cpp 文件中提供,并且一切正常。如果有的话,我看不出静态成员的模板定义和非模板定义之间的区别。
-
有一个很长的解释,但归根结底是如果你没有在头文件中提供定义并且另一个cpp用新类型实例化你的模板,那么编译器将不会实例化该静态成员为您(它没有实例化的定义)。这与您应该在标头中为模板提供函数定义的原因完全相同,并且可以以完全相同的方式避免它(在 cpp 中提供它并为您需要的所有类型强制实例化),但这会消除通用性: 新代码不能使用不同的参数。
标签: c++ templates static-members derived-class