我有一些遗留代码,而不是虚函数,使用kind
字段做动态调度。它看起来是这样的:没有虚函数的C++动态调度
// Base struct shared by all subtypes
// Plain-old data; can't use virtual functions
struct POD
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
};
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Derived1: POD
{
Derived1(): kind(Kind_Derived1) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived2: POD
{
Derived2(): kind(Kind_Derived2) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived3: POD
{
Derived3(): kind(Kind_Derived3) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
// ... and so on for other derived classes ...
,然后POD
类的成员函数都是这样实现的:
int POD::GetFoo()
{
// Call kind-specific function
switch (kind)
{
case Kind_Derived1:
{
Derived1 *pDerived1 = static_cast<Derived1*>(this);
return pDerived1->GetFoo();
}
case Kind_Derived2:
{
Derived2 *pDerived2 = static_cast<Derived2*>(this);
return pDerived2->GetFoo();
}
case Kind_Derived3:
{
Derived3 *pDerived3 = static_cast<Derived3*>(this);
return pDerived3->GetFoo();
}
// ... and so on for other derived classes ...
default:
throw UnknownKindException(kind, "GetFoo");
}
}
POD::GetBar()
,POD::GetBaz()
,POD::GetXyzzy()
,和其他成员也同样实施。
这个例子被简化了。实际的代码有大约十二种不同的子类型POD
,以及几十种方法。 POD
的新子类型和新方法会相当频繁地添加,所以每次我们这样做时,都必须更新所有这些switch
语句。
处理此问题的典型方法是在POD
类中声明函数成员virtual
,但我们不能这样做,因为对象驻留在共享内存中。有很多代码依赖于这些结构是普通的旧数据,所以即使我可以想出一些方法来在共享内存对象中使用虚函数,我也不想这样做。
所以,我正在寻找最好的方法来清理这个问题,以便所有关于如何调用子类型方法的知识都集中在一个地方,而不是分散在几十个switch
语句中几十个功能。
发生在我身上的是我可以创建某种类型的适配器类来包装POD
并使用模板来最小化冗余。但在我开始这条道路之前,我想知道其他人是如何处理这一问题的。
你说有很多的代码取决于这个类。你可以添加字段吗?还是结构需要保持不变? – 2011-01-14 16:35:09
结构应该保持基本相同。我们在共享内存中有大量这些东西,并且已经碰到内存大小的限制。 – 2011-01-14 16:44:04
是否所有的多个进程都具有完全相同的库版本,或者不是? – 2011-01-14 17:48:08