2010-11-17 59 views
2

有这个基本的层次:多态显式模板实例

// header 

class Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

class Subclass : Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

我想有两个明显的变化子类基地(无需提供子类,如果可能的两种实现),因此它已建议使用显式模板实例:

// header 

class Base 
{ 
    virtual void method() { } 
    virtual ~method() { } 
}; 

class Base1 : public Base { }; 
class Base2 : public Base { }; 

template <typename T>  
class Subclass : public T 
{ 
    virtual void method(); 
    virtual ~method() { } 
}; 

// cpp 

template <typename T> 
void Subclass<T>::method() 
{ 
} 

template class Subclass<Base1>; 
template class Subclass<Base2>; 

我得到这个错误:

there are no arguments to 'method' that depend on a template parameter, so a declaration of 'method' must be available

这是正确的方法吗?我显然必须模板Base才能编译,但是用什么?

+0

不要忘记虚拟析构函数。就像金钱和性不同,你需要去寻求它,否则你就不会得到它。 – wilhelmtell 2010-11-17 16:22:51

回答

0

问题和解决方案的小结:

为了从模板化基类中使用的方法要求要么使用模板参数:

T::method(); 

或者简单地使用“this”以允许在没有明确知道模板参数的情况下找到它:

this->method(); 

感谢那些指出我寻找这个解决方案的人,我并没有意识到这一点。也希望指出将模板放在cpp文件中没有问题。

2

您应该将模板类和函数的定义放在头文件中(它必须对谁使用它们是可见的)。

只能声明完整的特化(并定义代码在哪里没有可见性)。

此外,如果你要定义一个类模板出来的类的函数(像你一样),你必须声明为模板:

template< typename T > 
void Class<T>::method() 
{ 
} 

无论如何,如果我没有记错,当你使用函数method时,引用的错误是由你继承的类型名提供的(我认为你没有发布产生错误的代码段):它只能被找到当模板实际被实例化时,您需要明确地说它取决于模板参数。

呼叫method以这种方式:

T::method(); 
+0

我理想情况下不喜欢将定义放入头文件中,因为有很多计算,并且如果我可以避免它,编译时间就会增加? – Dan 2010-11-17 16:56:45

+0

所以没有办法使用多态性调用method()而不必知道基类是什么? – Dan 2010-11-17 17:00:21

+2

在这个时候希望在标题之外有模板,这真是不幸。试着与你的编译器厂商谈谈为模板实现“导出”......祝你好运。如果不知道底座在定义底座的派生内部,则无法在底座中调用method()。如果你从子类中移除方法(),它会起作用。否则,你必须使用答案中提到的语法。 – 2010-11-17 17:38:54