我有一个名为'ValueChecker'的课程
具有以下成员函数:
template<typename T>
bool ValueChecker::checkMe( std::ostringstream &oss, T &me) {
std::cout << "Default checkMe() for " << typeid(me).name() << std::endl;
return true;
}
ValueChecker类旨在对派生类的值进行一些简单的检查。 checkMe()最终会专门针对不同的派生类:
class Airplane : public ValueChecker {
friend class ValueChecker;
[...]
}
template<>
bool ValueChecker::checkMe<Airplane>( std::ostringstream &oss, Airplane &me) {
...
/* Actually, this code is generated from a simple file which translates
* a simple language into C++ code. So that a non-developer can write
* the simple checks.
*
* ValueChecker itself has utility functions that may be called in the
* template specialization which are shared across all types.
*/
}
这很有效,但是当您查看调用时,checkMe的声明只有一个小问题:
int main() {
Airplane plane;
std::ostringstream oss;
if( plane.checkMe( oss, plane)) {
cout << "Values are bogus! " << oss.str() << endl;
return 0;
}
我打电话给plane.checkMe(oss,plane)。但是,我也可以通过另一架飞机,而不是检查飞机。此外,调用是多余的?从理论上讲,编译器应该根据平面的类型知道要调用哪个模板函数。不应该将它作为参数传递给它吗?无论如何,不要消除最后一个参数会很好。所以像这样的电话会很好:
if( plane.checkMe(oss)) { ... } // Calls the right template specialization.
我无法让它发挥作用。这里的C ++大师可以帮助我吗?感谢。
答案 0 :(得分:3)
您可能希望将其实现为纯虚方法。
class ValueChecker
{
public:
virtual bool checkMe(std::ostringstream& oss) = 0;
};
class Airplane : public ValueChecker
{
public:
virtual bool checkMe(std::ostringstream& oss);
};
这样你就可以调用plane.checkMe(oss)
并调用飞机的checkMe-Method。
答案 1 :(得分:3)
对于您的代码,您实际上不需要使用template
或friend
。而是使用继承,并将checkMe()
方法设为protected
和virtual
方法。然后覆盖派生类中的checkMe()
方法。如果您不需要默认实现,您也可以将其设为纯虚拟实现。这是一个基于您的示例的快速代码段。 (注意使用this
指针。)
class ValueChecker {
protected:
virtual bool checkMe() {
std::cout << "Default checkMe() for " << typeid(this).name() << std::endl;
return true;
}
};
class Airplane : public ValueChecker {
public:
virtual bool checkMe() {
std::cout << "Airplane checkMe() for " << typeid(this).name() << std::endl;
return true;
}
};
int main() {
Airplane plane;
plane.checkMe();
}
除了特定于派生类本身的逻辑之外,当您想要在一个或多个派生类中使用某些“通用”逻辑时,您将需要一个默认实现。在这种情况下,使用范围解析运算符来访问基类的逻辑。
bool Airplane::checkMe() {
std::cout << "Airplane checkMe() for " << typeid(this).name() << std::endl;
// use the "common" logic from the base class (if required)
ValueChecker::checkMe();
return true;
}
答案 2 :(得分:0)
经常有一个常见的伎俩:http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 这可以帮到你。