1

我有一个基类B和几个派生的模板类,,,,D<int>等等D<float>D<double>这么多)

在我的程序中,我发现我有一个 B 指针,我知道该指针指向 D 特化之一的实例。我还有一个标识派生类型的唯一键。

所以,我想使用我的基类指针和唯一类型键调用正确的派生类方法。我实际上想在几个地方这样做,所以我想出的一个解决方案不仅丑陋,而且很麻烦。

有没有更好的方法来访问在 C++ 中具有基指针和唯一键的派生类成员?

我不想/不能修改基类。boost库是公平的游戏。

这是我的潜在代码,但我不喜欢在需要访问派生成员函数/变量的任何地方复制它。所有这一切都是为了一个成员函数调用?!!

B * bptr = ...
std::type_info * typekey = ...

if        (typekey == &typeid(D<float>) ) {
    D<float> * dptr = static_cast<D<float>*>(bptr);
    dptr->derivedMember();
} else if (typekey == &typeid(D<double>) ) {
    D<float> * dptr = static_cast<D<double>*>(bptr);
    dptr->derivedMember();
} else if (typekey == &typeid(D<int>) ) {
    D<float> * dptr = static_cast<D<int>*>(bptr);
    dptr->derivedMember();
} 
4

3 回答 3

2

如果所有D<type>::方法都具有相同的名称“DerivedMember”,并且我假设基类 B 没有将其声明为虚拟,那么您可以从以下位置更改您的层次结构:

class B { etc. };

template<class T>
class D : public B
{
};

到:

class B { etc. };

class C : public B
{
 virtual void derivedMember() = 0;
};


template<class T>
class D : public C
{
public:
void derivedMember() { etc. };
};

然后你可以有:

void f(C* c) /* or take a B* and do: C* c = static_cast<C*>(b); */
{    
  c->derivedMember();
}
于 2012-01-05T02:42:29.760 回答
0

如评论中所述,处理这种情况的正确方法是引入一种virtual方法并让 C++ 正确调度调用。

由于不能修改基类,因此可以插入具有虚函数的新类,并从新类派生所有类。

如果您需要使用许多功能(可能尚未定义且客户端代码将提供的功能)复制此行为,您可以利用访问者模式。事实上,如果您无法更改基类,您至少可以使用类似 Vistior 的技术将繁琐的 typekey 检查保留在一个位置,并将实际操作取出到单独的类中。如果另一个类似函数,这将使您不必重写 typekey 检查derivedMember

于 2012-01-05T02:45:10.433 回答
0

我认为使用 dynamic_cast 可以解决这个问题:

    B* base
    if(Class1* c1 = dynamic_cast<Class1*>(base))
    // it's a Class1*
    else if (Class2* c2 = dynamic_cast<Class2*>(base))
    // it's a Class2*
于 2012-01-05T10:37:39.443 回答