【发布时间】:2011-07-15 22:30:32
【问题描述】:
我正在使用的某些代码的当前版本使用了一种稍微奇怪的方式来实现我认为可以通过多态性来实现的东西。更具体地说,我们目前使用类似
for(int i=0; i<CObjList.size(); ++i)
{
CObj* W = CObjList[i];
if( W->type == someTypeA )
{
// do some things which also involve casts such as
// ((SomeClassA*) W->objectptr)->someFieldA
}
else if( W->type == someTypeB )
{
// do some things which also involve casting such as
// ((SomeClassB*) W->objectptr)->someFieldB
}
}
澄清;每个对象 W 都包含一个void *objectptr;,即指向任意位置的指针。 W->type 字段跟踪 objectptr 指向的对象类型,以便在 if/else 语句中,我们可以将 W->objectptr 转换为正确的类型并使用它的字段。
但是,从代码设计的角度来看,这似乎天生就很糟糕,原因有几个;
- 我们无法保证
W->objectptr指向的对象实际上与W->type中所说的内容相匹配,因此强制转换本质上是不安全的。 - 每次我们希望添加另一种类型时,都必须添加另一个 elseif 语句并确保
W->type设置正确。
似乎用类似的东西解决这个问题会好得多
class CObj
{
public:
virtual void doSomething(/* some params */)=0;
};
class SomeClassA : public CObj
{
public:
virtual void doSomething(/* some params */);
int someFieldA;
}
class SomeClassB : public CObj
{
public:
virtual void doSomething(/* some params */);
int someFieldB;
}
// sometime later...
for(int i=0; i<CObjList.size(); ++i)
{
CObj* W = CObjList[i];
W->doSomething(/* some params */);
}
话虽如此,但前提是在此设置中性能很重要。此代码将从(相对)紧密的循环中调用。
那么我的问题是;一些 vtable 查找所增加的复杂性是否被改进的代码设计和可扩展性所抵消,这是否可能对性能产生很大影响?
编辑:我突然想到,由于缓存未命中等原因,以这种方式通过指针访问字段可能与 vtable 查找一样糟糕。对此有什么想法吗?
---- 编辑 2:我也忘了提及(我知道这有点偏离原始主题),在 if 语句内部有许多对周围类的成员函数的调用。您将如何设计结构以便能够从 doSomething() 内部调用这些?
【问题讨论】:
-
你真的对此做过一些性能测试吗?还是您“优化得太早了?”
-
虽然基于类的 OOP 可能并不完美,但不妨利用它所提供的优势......在这种情况下,是一种多态性。
-
您是否尝试测量性能差异?如果没有太大区别,那么更简洁的代码将为可维护性带来巨大的好处。
-
尚未尝试衡量差异,因为这需要很多地方进行更改。此外,通过谷歌搜索,很多人认为简单的测试可能不具有代表性。
-
@Dan:这是一个嵌入式系统吗?如果是这样,请考虑标记“嵌入式”——您会得到与“直接”C++ 略有不同的答案,因为性能/可维护性的权衡对于嵌入式编码人员来说通常更明显。
标签: c++ oop polymorphism vtable