我有一个基类B
和几个派生模板类D<int>
,D<float>
,D<double>
等(超过十个)
在我的程序中,我发现一种情况,我有一个B指针,我知道指向一个D特化的实例之一。我还有一个标识派生类型的唯一键。
所以,我想使用我的基类指针和唯一类型键调用正确的派生类方法。我实际上想在几个地方做这个,所以我想出的一个解决方案不仅难看,而且很麻烦。
有没有更好的方法来访问派生类的成员在C ++中具有基指针和唯一键?
我不想/不能修改基类。提升图书馆是公平的游戏。
这是我的潜在代码,但我不满意在需要访问派生成员函数/变量的任何地方复制它。所有这一切都用于一个成员函数调用?!!
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();
}
答案 0 :(得分: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();
}
答案 1 :(得分:0)
正如评论中所指出的,处理这种情况的正确方法是引入virtual
方法并让C ++正确调度调用。
由于无法修改基类,因此可以使用虚函数插入新类,并从新类派生所有类。
如果您需要使用许多函数复制此行为,可能还有尚未定义且客户端代码将提供的函数,您可以利用Visitor pattern。事实上,如果你不能改变基类,你至少可以使用类似Vistior的技术将繁琐的typekey检查保存在一个位置,并取出实际操作来分离类。这将使您不必重写typekey检查另一个derivedMember
- 类似函数。
答案 2 :(得分: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*