我最近一直在刷新/更新我对 C++ 的了解,并且学习严格的别名让我对将一种类型的指针转换为另一种类型的指针有点警惕。我知道以下代码示例在我的编译器上实际工作,但我想确保它符合当前标准:
#include <iostream>
using namespace std;
class MyBase {
public:
virtual void DoSomething() = 0;
};
class MyDerived1 : public MyBase {
public:
virtual void DoSomething() {
cout << "I'm #1" << endl;
}
};
class MyDerived2 : public MyBase {
public:
virtual void DoSomething() {
cout << "I'm #2" << endl;
}
};
template <typename Base, typename Member1, typename Member2>
struct Tuple {
public:
Base* Get(int i) {
return &(this->*(lookupTable[i]));
}
private:
Member1 member1;
Member2 member2;
static Base Tuple::* const lookupTable[2];
};
template <typename Base, typename Member1, typename Member2>
Base Tuple<Base, Member1, Member2>::* const Tuple<Base, Member1, Member2>::lookupTable[2] = {
reinterpret_cast<Base Tuple<Base, Member1, Member2>::*>(&Tuple::member1),
reinterpret_cast<Base Tuple<Base, Member1, Member2>::*>(&Tuple::member2)
};
int main() {
Tuple<MyBase, MyDerived1, MyDerived2> tuple;
tuple.Get(0)->DoSomething();
tuple.Get(1)->DoSomething();
return 0;
}
本质上,这个简单的元组包含一对元素,每个元素都应该派生自一个公共基类。Get 函数将 a 返回Base*
给给定索引表示的成员。
我想知道的关键部分是 reinterpret_casts。我知道从Derived Struct::*
to转换Base Struct::*
通常是禁止的,但在这种情况下,我只使用指向成员变量的指针来获取指向对象的指针。(我不会尝试将派生对象复制为基础对象,也不会将基础对象填充到派生对象的内存中。)这在 G++ 上按预期工作,我只是想确定我不是这样做会被任何兼容的编译器咬伤。