C++中如何从类实例指针与成员普通指针获取成员指针?
如何从对象实例指针和成员普通指针转换为成员指针?
嘿,你说到点子上了——成员指针的核心确实就是对象实例和成员之间的内存偏移量,所以这个转换完全可行,咱们直接来看具体实现:
实现思路
对于非虚成员来说,int S::*类型的成员指针本质上存储的是该成员相对于对象起始地址的偏移值。我们只需要计算出给定的成员普通指针p与对象指针s之间的偏移量,再将这个偏移量转换回成员指针类型即可。
代码实现
#include <cstddef> // 需要包含这个头文件来使用ptrdiff_t struct S { int i; }; // 已知的正向转换函数 int* from_mptr(S* s, int S::* mp) { return &(s->*mp); } // 你需要的反向转换函数 int S::* to_mptr(S* s, int* p) { // 计算成员相对于对象起始地址的字节偏移 ptrdiff_t offset = reinterpret_cast<char*>(p) - reinterpret_cast<char*>(s); // 将偏移量转换为对应的成员指针类型 return reinterpret_cast<int S::*>(offset); }
关键注意事项
- 仅适用于非虚成员:如果是虚成员,其地址涉及虚表机制,不是固定的内存偏移,这种转换方式完全不适用,强行转换会导致未定义行为。
- 确保指针合法性:必须保证传入的
p确实是s这个实例中对应类型成员的指针。如果p指向的是其他对象的成员、独立变量或者堆上无关内存,转换结果毫无意义,同样属于未定义行为。
测试验证
咱们写个简单的测试代码验证一下转换是否正确:
#include <iostream> int main() { S test_obj; test_obj.i = 123; // 正向转换:成员指针 -> 普通指针 int S::* member_ptr = &S::i; int* normal_ptr = from_mptr(&test_obj, member_ptr); std::cout << "普通指针指向的值:" << *normal_ptr << std::endl; // 输出123 // 反向转换:普通指针 -> 成员指针 int S::* converted_member_ptr = to_mptr(&test_obj, normal_ptr); std::cout << "转换后的成员指针指向的值:" << test_obj.*converted_member_ptr << std::endl; // 输出123 return 0; }
运行这段代码,两次输出都是123,说明转换是成功的。
内容的提问来源于stack exchange,提问作者Gábor
相关产品推荐
相关产品推荐

