C++转换:具有指向对象成员的指针,计算指向对象的指针



C++有static_castbase_class_pointer转换为derived_class_pointer

object_data_member_pointer转换为object_pointer是非常相似的操作。

我使用不安全的C类型转换编写了函数ConvertDataMemberPtrToObjectPtr

  • 如何以安全的方式做到这一点?指向成员的链接必须指定为模板参数member_ptr
  • 如果使用这样的实现,是否会出现任何问题

来源:

#include <stdio.h>
#include <tchar.h>
template< class T, class Member_type, Member_type T::*member_ptr >
inline T *ConvertDataMemberPtrToObjectPtr(Member_type& member) {    
    //Got reference to member 'member' of object 'T', return pointer to object 'T'
    // obj_ptr = member_ptr - offset_of_member_field
    return (T*) ( ((char*)(&member)) - ( (char*) (  &( ((T*)(0))->*member_ptr ) )  ) );
}
struct Test {
    int a;
    int b;
};
int _tmain(int argc, _TCHAR* argv[]) {
    Test obj;
    printf("n0x%08lX", ConvertDataMemberPtrToObjectPtr<Test,int,&Test::a>(obj.a));
    printf("n0x%08lX", ConvertDataMemberPtrToObjectPtr<Test,int,&Test::b>(obj.b));
    // This is must be avoided when using ConvertDataMemberPtrToObjectPtr!!!
    printf("n0x%08lX - error!", ConvertDataMemberPtrToObjectPtr<Test,int,&Test::a>(obj.b));
    return 0;
}

使用父代成员和static_cast:

template <class T, int id=0>
class Link {
public:
    int value;
    T *GetObjectPtr() { return static_cast<T*>(this); }
};
enum MyLinkId { Main=0, Red=1 };
class MyItem : public Link<MyItem,Main>, public Link<MyItem,Red> {};
MyItem x;
Link<MyItem,Main> *p2 = &x;
Link<MyItem,Red> *p3 = &x;
printf("n0x%08lX", p2->GetObjectPtr());
printf("n0x%08lX", p3->GetObjectPtr());

您想要实现的是不可能的:缺少区分成员的信息。您需要一个唯一的引用成员,可以将其传递给转换函数。

struct UniqueReferenceMember {};
struct Test {
    UniqueReferenceMember unique_reference_member;
    int a;
    int b;
};

不过,这样做毫无意义。有一个对象指针,您可以直接传递(可能转换为void*);

相关内容

  • 没有找到相关文章

最新更新