具有固定实现的虚函数不使用大多数派生类 for (*this)
假设我有以下代码:
struct Z;
struct A
{
virtual void Do (Z & z) const;
};
struct B : public A {};
struct Z
{
void use (A const & a) {}
void use (B const & b) {}
};
void A::Do(Z& z) const{
z.use(*this);
}
现在,当我调用 B.do
时,this
的类型是 A
,这是有道理的,因为do
的实现是在A
中定义的。
有没有办法让对 B.do
的调用使用 use (B const &)
而不必为 do
复制粘贴相同的代码> 从A
到B
?在我的实际代码中,我有大约 15 个(并且还在不断增加)从某个基类派生的类,每次都必须为 do
复制粘贴相同的代码似乎很浪费。
[编辑]澄清:所有Do
所做的就是调用use
,没有别的。 Do
和 use
是接受和使用。访问访问者模式中的函数。
Let's say I have the following code:
struct Z;
struct A
{
virtual void Do (Z & z) const;
};
struct B : public A {};
struct Z
{
void use (A const & a) {}
void use (B const & b) {}
};
void A::Do(Z& z) const{
z.use(*this);
}
Right now, when I call B.do
, the type of this
is A
, which make sense, because the implementation of do
is defined in A
.
Is there any way to have calls to B.do
use use (B const &)
without having to copy-paste the same code for do
from A
into B
? In my actual code I have about 15 (and growing) classes derived from some base class and it seems a waste having to copy-paste the identical code for do
everytime.
[Edit] Clarification: all Do
does is call use
, nothing else. Do
and use
are the accept & visit functions from the Visitor pattern.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
既然您现在澄清了您想要的是访问者模式,那么抱歉,但事实就是如此。 此答案展示了双重调度的访问者模式的工作原理。
我想到了一个使用 CRTP 的好方法,但这可能适合你,也可能不适合你,具体取决于具体情况。
(注意:我使用了链接答案中的代码,因此名称不匹配,但我希望您明白。)
唯一的问题:现在您错过了机会拥有任何类型的A
的通用句柄,因为函数不能同时是虚拟函数和模板函数。 :|刮了一下,找到了使用 Superbase 基类的解决方案。 :) 这甚至允许您拥有 Superbase 的容器并充分利用多态性。 :)
Since you now clarified that what you want is the visitor pattern, well, sorry, but that's just how it is. This answer shows how the visitor pattern with double dispatch works.
I thought of a nice way using CRTP, but this may or may not work for you, depending on the circumstances.
(Note: I used the code from the linked answer, so the names don't match, but I hope you get the idea.)
The only problem: Now you're missing the chance to have a generic handle to any type ofA
, since functions can't be both virtual and templates. :|Scrape that, found a solution using a
Superbase
base class. :) This even allows you to have a container ofSuperbase
s and take full advantage of polymorphism. :)我认为这段代码可以满足您的要求:
代码中唯一的“维护”或“样板”部分是从根据您自己的类型模板化的模板类派生的。
I think this code does what you want:
The only 'maintenance' or 'boiler-plate' part of the code is to derive from the template class templated on your own type.
您需要根据
this
指向的类型分派use
的调用,因此您需要向A
和添加另一个虚拟函数>B
只需调用正确的use
。我假设do
除了调用use
之外还做了其他事情,否则你确实必须在每个子类中重新实现do
。它看起来像这样You need to dispatch the call of
use
based on the type pointed to bythis
so you need to add another virtual function toA
andB
that simply invokes the correctuse
. I assume thatdo
does other things than calluse
of course otherwise you would indeed have to re-implementdo
in each subclass. It would look like this我想我必须让你失望并且说不。这是您必须做出的权衡,以便将接口从您的类分解到访问者中。访问者必须知道哪一个向它汇报,只要你不重写基类中的虚拟Do(),访问者就会把你当作A。
请有人证明我错了! (我还看到这个解决方案以消除冗余)
I think I have to disappoint you and say no. This is the trade off you have to make, in order for you to break out the interface from your classes into the visitor. The visitor must know which one is reporting to it, as long as you don't override the virtual Do() in the base class, the visitor will treat you as A.
Please someone prove me wrong! (I'd also see this solved to remove redundancy)