c++ - 是否可以将常规指针转换为指向类字段的指针

标签 c++ pointers type-conversion field

给定一个类实例和指向一个字段的指针,我们可以获得指向此类实例的字段变量的常规指针——如以下代码中的最后一个赋值;

class A
{
public:
    int i, j;
};
int main(){
    A a;
    int A::*p = &A::i;
    int* r = &(a.*p); // r now points to a.i;
}

是否可以反转此转换:给定类实例 A a;int* r 获得 int A::* p (或 NULL ptr,如果给定的指针未在实例中给出)如代码所示:

class A
{
public:
    int i, j;
};
int main(){
    A a;
    int A::*p = &A::i;
    int* r = &(a.*p); // r now points to a.i;
    int A::*s = // a--->r -how to extract r back to member pointer?
}

我能想到的唯一方法是编写一个函数,获取 A 的每个已知字段,计算给定实例的地址并与给定地址进行比较。然而,这需要为每个类编写自定义代码,并且可能难以管理。它的性能也不理想。

我可以想象,在我所知道的所有实现中,编译器可以通过很少的操作完成这种转换——这样的指针通常只是结构中的一个偏移量,所以它只是一个减法和范围检查,看看给定的指针是否真的在此类存储。虚拟基类增加了一点复杂性,但我认为没有什么是编译器无法处理的。然而,似乎因为它不是标准所要求的(是吗?),所以没有编译器供应商关心。

或者我错了,这种转换存在一些根本问题?

编辑:

我发现我问的问题有点误解。简而言之,我想问的是:

  • 已经有它的一些实现(我的意思是在编译器级别),但由于几乎没有人使用它,几乎没有人知道它。
  • 标准中没有提及它,也没有编译器供应商想到它,但原则上它是可以实现的(再一次:通过编译器,而不是编译代码。)
  • 这种操作存在一些影响深远的问题,但我没有注意到。

我的问题是 - 哪一个是正确的?如果是最后一个 - 根本问题是什么?

我不要求解决方法。

最佳答案

没有跨平台的方法可以做到这一点。指向成员值的指针通常实现为对象开头的偏移量。利用这个事实我做了这个(在 VS 中工作,没有尝试过其他任何东西):

class A
{
public:
    int i, j;
};

int main()
{
    A a;
    int A::*p = &A::i;
    int* r = &(a.*p); // r now points to a.i;

    union
    {
        std::ptrdiff_t offset;
        int A::*s;
    };

    offset = r - reinterpret_cast<int*>(&a);
    a.*s = 7;
    std::cout << a.i << '\n';
}

关于c++ - 是否可以将常规指针转换为指向类字段的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12466439/

相关文章:

java - 从文件中获取一个重复的字段而不需要加载整个文件

c++ - 使用 GDB 的 Python pretty-print 不支持 map 的索引运算符 []

c++ - 如何访问封装在类中的未命名的 "enum class"?

c++ - 添加同名方法后继承的模板化方法不可见

mysql - 使用 vb.net 将数据集值移动到标签框控件时出错

error-handling - iOS Swift5如何检查对象的类型是否在[Class.Type]类型的数组中声明?

c - 禁忌搜索算法总是在第二次迭代时崩溃

c++ - 动态创建指针数组时,Visual Studio 不显示完整数组

c++ - 在 C++ 中转换函数指针的奇怪行为

javascript - 如何将整数数组转换为对象数组?