我在写C++。
我有不同的类从基类继承(例如,A,B,C,D 都继承自 Z(。
我想编写一个函数,该函数接受 2 个类型(超类型(Z 的对象并执行一些操作。(例如,我可以有f(a, b)
或f(c,d)
,其中 a、b、c、d 分别属于 A、B、C、D 类型(。
我希望(函数的(接口是通用的(没有f_AB(a,b)
和f_CD(c,d)
(。
但是,实现可以(并且确实(根据所采用的类而有所不同。(例如,我确实有f_AB
做一些特定于 A-B 的事情,f_CD
做一些特定于 C-D 的事情,以及f_AC
、f_BC
等(
子类具有完全不同的数据,并且根据我比较的类,具体操作完全不同。
当我使用这个函数时,我不知道 2 个参数的特定子类。假设我正在做类似的事情
for p in Z {
for q in Z
f(p, q) # p and q could be of any subclass of Z! and f must behave accordingly!
}
在C++解决这个问题的最佳方法是什么?我无法结合多态性、虚拟方法、重载和动态强制转换来完全解决问题。
如果这无法解决,是否有可能通过放弃一些假设来解决它?(就像使用继承一样,这实际上只是为了具有通用引用来循环我的对象(
这应该可以:
class A;
class B;
class C;
class D;
class ZVisitor;
class Z
{
public:
virtual void Accept (ZVisitor *zv) = 0;
virtual void f(A* a) = 0;
virtual void f(B* b) = 0;
virtual void f(C* c) = 0;
virtual void f(D* c) = 0;
};
class A : public Z
{
public:
void Accept(ZVisitor *zv)
{
zv->Handle(this);
}
void f(A* a);
void f(B* b);
void f(C* c);
void f(D* c);
};
class B : public Z
{
public:
void Accept(ZVisitor *zv)
{
zv->Handle(this);
}
void f(A* a);
void f(B* b);
void f(C* c);
void f(D* c);
};
class C : public Z
{
public:
void Accept(ZVisitor *zv)
{
zv->Handle(this);
}
void f(A* a);
void f(B* b);
void f(C* c);
void f(D* c);
};
class D : public Z
{
public:
void Accept(ZVisitor *zv)
{
zv->Handle(this);
}
void f(A* a);
void f(B* b);
void f(C* c);
void f(D* c);
};
class ZVisitor
{
private:
Z *z;
public:
ZVisitor(Z *z)
{
this->z = z;
}
void Handle(A* a)
{
z->f(a);
}
void Handle(B* b)
{
z->f(b);
}
void Handle(C* c)
{
z->f(c);
}
void Handle(D* d)
{
z->f(d);
}
};
void f(Z *z1, Z *z2)
{
ZVisitor zvisitor(z2);
z1->Accept(&zvisitor);
}