访客:通过继承添加更多类型
我想通过继承扩展已声明的访问者,并让运行时环境搜索访问者的后代以获取要执行的正确方法。我可以在 C# 中使用它,但我希望在 C++ 中使用它。我在 g++ 中尝试了以下代码,但未调用派生方法;仅调用基类的方法。
#include <iostream>
using namespace std;
struct Field; // Forward declaration
struct Visitor
{
virtual void visit(Field& f) = 0; // Visits Field objecs and objects derived from Field.
};
struct Field_String;
struct Visitor_Field_String : public Visitor
{
// Extend the Visitor by specifying a visitation
// for Field_String
virtual void visit(Field_String& fs) = 0;
};
struct Field
{
void accept_visitor(Visitor& v)
{
cout << "Field accepting visitor.\n";
v.visit(*this);
}
};
struct Field_String : public Field
{
void accept_visitor(Visitor& v)
{
cout << "Field_String accepting visitor.\n";
v.visit(*this); // Line 1
}
};
struct Full_Visitor : Visitor_Field_String
{
void visit(Field& f)
{
cout << "Visiting a Field object\n";
return;
}
void visit(Field_String& fs)
{
cout << " Visiting a Field_String object\n";
return;
}
};
int main(void)
{
Field_String fs;
Full_Visitor visitor;
fs.accept_visitor(visitor);
return 0;
}
我得到以下输出:
# g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# g++ -o virtual_visitor.exe virtual_visitor.cpp
# ./virtual_visitor.exe
Field_String accepting visitor.
Visiting a Field object
我想要的输出是:
Field_String accepting visitor.
Visiting a Field_String object
我的两个问题:
- 为什么
visit
方法在 后裔访客没有被处决? - 如何执行
visit
方法 在后代访客中使用 多态性?
注意:目标是通过使用继承并允许可能不使用 Visitor 中指定的所有类的情况来减少 Visitor 类中指定的类。
注意:这是不是双重调度,而是延长调度。
I want to expand a declared Visitor through inheritance and have the run-time environment search the descendents of the Visitor for the correct method to execute. I can have this in C#, but I'm looking to use it in C++. I tried the following code in g++ and the descendent method is not called; only the method for the base class is called.
#include <iostream>
using namespace std;
struct Field; // Forward declaration
struct Visitor
{
virtual void visit(Field& f) = 0; // Visits Field objecs and objects derived from Field.
};
struct Field_String;
struct Visitor_Field_String : public Visitor
{
// Extend the Visitor by specifying a visitation
// for Field_String
virtual void visit(Field_String& fs) = 0;
};
struct Field
{
void accept_visitor(Visitor& v)
{
cout << "Field accepting visitor.\n";
v.visit(*this);
}
};
struct Field_String : public Field
{
void accept_visitor(Visitor& v)
{
cout << "Field_String accepting visitor.\n";
v.visit(*this); // Line 1
}
};
struct Full_Visitor : Visitor_Field_String
{
void visit(Field& f)
{
cout << "Visiting a Field object\n";
return;
}
void visit(Field_String& fs)
{
cout << " Visiting a Field_String object\n";
return;
}
};
int main(void)
{
Field_String fs;
Full_Visitor visitor;
fs.accept_visitor(visitor);
return 0;
}
I get the following output:
# g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# g++ -o virtual_visitor.exe virtual_visitor.cpp
# ./virtual_visitor.exe
Field_String accepting visitor.
Visiting a Field object
The output I want is:
Field_String accepting visitor.
Visiting a Field_String object
My two questions:
- Why is the
visit
method in the
descendent Visitor not executed? - How do I execute the
visit
method
in the descendent Visitor using
polymorphism?
Note: The objective is to reduce the classes specified in a Visitor class, by using inheritance and allowing for the cases that may not use all of the classes specified in the Visitor.
Note: This is not double dispatch, but extended dispatch.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你不能在 C++ 中做到这一点(你真的可以在 C# 中做到这一点吗?)关于特定问题:
编译器根据引用的静态类型和该函数的最终重写者解析要使用的函数重载基于对象的动态类型。
您需要在基类中提供所有不同的重载。如果你做不到,你可以做一些令人讨厌的事情,比如
dynamic_cast
来尝试确定收到的Visitor
是否支持该特定字段,但我会避免这样做所有费用。调度*。
由于不同的字段类型没有被多态地使用(或者至少看起来不像,因为
accept_visitor
函数不是虚拟的),为什么不接受具体的访问者类型?You cannot do that in C++ (can you really do it in C# without reflection?) On the particular questions:
The compiler resolves the function overload to use based on the static type of the reference, and the final overrider of that function based on the dynamic type of the object.
You need to provide all of the different overloads in the base class. If you cannot do it, you can do nasty things like
dynamic_cast
's to try and determine whether theVisitor
received has support for that particular field, but I would avoid it at all costs.dispatch*.
Since the different field types are not being used polymorphically (or at least it does not seem like it, since the
accept_visitor
functions are not virtual), why don't you accept the concrete visitor type?您是否有理由必须从
Visitor
虚拟类派生第二个Visitor_Field_String
虚拟类类型?例如,如果您像这样定义基本Visitor
和Full_Visitor
类:您将获得您正在寻找的功能。您想要做的问题是
fs.accept_visitor(visitor)
被多态转换为的类类型是Visitor
对象类型,仅定义了virtual void Visit(Field& f)
。因此,在Visitor
类型的类上调用visit()
,无需对内的
函数不会引用Visitor_Field_String
类类型进行某种类型的额外转换Accept_visitor()visit()
函数的其他重载版本,因为它们是在派生类中定义的。Is there a reason you have to derive a second
Visitor_Field_String
virtual class type from youVisitor
virtual class? For instance, if you define your baseVisitor
andFull_Visitor
classes like this:you'll get the functionality you're looking for. The problem with what you're trying to-do is that the class-type that
fs.accept_visitor(visitor)
is being polymorphically cast to is aVisitor
object-type which only hasvirtual void visit(Field& f)
defined. So callingvisit()
on a class of typeVisitor
, without some type of additional cast to aVisitor_Field_String
class-type inside youraccept_visitor()
functions will not refer to the additional overloaded versions of yourvisit()
function as they're defined in the derived class.