【发布时间】:2014-08-17 19:56:10
【问题描述】:
此问题涉及使用模板来解析 Dispatch 模式中的虚拟成员。
注意:这与 StackOverflow 上已经提出的虚拟模板方法问题不同。 *
编辑 1:更正语法错误,添加说明。
鉴于以下情况:
#include <string>
#include <iostream>
class Field_Interface
{
public:
virtual std::string get_field_name(void) const = 0;
};
class Field_Integer : public Field_Interface
{
public:
std::string get_field_name(void) const
{ return "INT";}
};
class Field_String : public Field_Interface
{
public:
std::string get_field_name(void) const
{ return "VARCHAR";}
};
class Field_Double : public Field_Interface
{
public:
std::string get_field_name(void) const
{ return "DOUBLE";}
};
class Abstract_Visitor
{
public:
virtual void visit(const Field_Integer& fi) = 0;
virtual void visit(const Field_String& fi) = 0;
virtual void visit(const Field_Double& fi) = 0;
};
class Visitor_Name_Query_1 : public Abstract_Visitor
{
public:
template <class Field>
void visit(const Field& f)
{
std::cout << "Field name is: "
<< f.get_field_name()
<< "\n";
}
};
class Visitor_Name_Query_2 : public Abstract_Visitor
{
public:
void visit(const Field_Integer& fi)
{ print_field_name(fi); }
void visit(const Field_String& fi)
{ print_field_name(fi); }
void visit(const Field_Double& fi)
{ print_field_name(fi); }
private:
void print_field_name(const Field_Interface& fi)
{
std::cout << "Field name is: "
<< fi.get_field_name()
<< "\n";
}
};
int main(void)
{
Visitor_Name_Query_1 q1;
Field_Integer fi;
q1.visit(f1);
return 0;
}
编译器说Visitor_Name_Query_1 中的模板化方法没有解析来自Abstract_Visitor 的抽象接口。
编辑 2:g++ 的结果
# g++ -o main.exe main.cpp
main.cpp: In function `int main()':
main.cpp:75: error: cannot declare variable `q1' to be of type `Visitor_Name_Query_1'
main.cpp:75: error: because the following virtual functions are abstract:
main.cpp:35: error: virtual void Abstract_Visitor::visit(const Field_Integer&)
main.cpp:36: error: virtual void Abstract_Visitor::visit(const Field_String&)
main.cpp:37: error: virtual void Abstract_Visitor::visit(const Field_Double&)
main.cpp:77: error: `f1' undeclared (first use this function)
main.cpp:77: error: (Each undeclared identifier is reported only once for each function it appears in.)
Visitor_Name_Query_1 是一种简化Visitor_Name_Query_2 类的尝试。当visit 方法的数量超过一个简单的数量(如5 个)时,维护变得乏味。这就是template 声明的原因。
扩展模板时,使用其中一种字段类型,声明与Visitor_Name_Query_2 中的声明匹配。
那么为什么编译器生成说class Visitor_Name_Query_1 是抽象的?
注意:我在 Windows Vista 上使用 Visual Studio 2008。
* 其他帖子涉及使用模板来创建虚拟方法声明。我正在使用模板来创建实现抽象方法的函数。
【问题讨论】:
-
类成员模板不能是虚拟的。
-
当你说“这不一样”时,你的意思实际上是“这完全一样”吗?
-
当我修复所有似乎与您的问题完全无关的编译器错误(例如语法错误和缺少继承)时,在 VC 2013 中编译时甚至没有警告。
-
@ChristianHackl It doesn't compile with
Visitor_Name_Query_1class instantiated,当然。 -
使用模板。
Abstract_Visitor是不必要的,所以去掉它。
标签: c++ templates visual-studio-2008 dispatch visitor-pattern