c++ - 在这种情况下可以强制转换指向成员变量的指针吗?

标签 c++ pointers casting member strict-aliasing

我最近一直在刷新/更新我对 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;

}

本质上,这个简单的元组包含一对元素,每个元素都应该派生自一个公共(public)基类。 Get 函数返回一个 Base* 给给定索引代表的成员。

我想知道的关键部分是 reinterpret_casts。我知道从 Derived Struct::*Base Struct::* 的转换通常是不行的,但在这种情况下我只使用 pointers-to-member-variable 获取对象的指针。 (我不会尝试将派生对象当作基础对象来复制,也不会将基础对象填充到派生对象的内存中。)这在 G++ 上按预期工作,我只是想确保我不是这样做会被任何兼容的编译器咬住。

最佳答案

你不应该在那里使用 reinterpret_cast。实际上,您不应该在目标是可移植性的任何地方提及 reinterpret_cast 的使用。根据定义,reinterpret_cast 具有特定于平台的结果。

要将指向基类的指针转换为派生类的指针,请使用 dynamic_cast,当指向的对象不是派生类时,它将返回 NULL。如果您绝对确定该类是正确的,那么您可以使用 static_cast。

关于c++ - 在这种情况下可以强制转换指向成员变量的指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4582346/

相关文章:

c++ - 在哪里可以设置 Eclipse C++ 函数名称样式?

c++ - boost::accumulators::statistics 的中值输出令人困惑

c++ - 我们如何让一个共享指针指向另一个共享指针的对象呢?

捕捉奇怪的 C 指针算术错误

arrays - 将对象数组转换为数组数组

c - 如何安全地将 void* 转换为 C 中的 int?

c++ - 将 TCHAR 与字符串进行比较

c++ - 在 typedef 中使用 type 时包含在头文件中的规则

c - 指向从原始结构中丢失数据的结构的指针

c# - 将 Generic<Derived> 转换为 Generic<Base>