【发布时间】:2014-01-02 01:07:15
【问题描述】:
C++ 有static_cast 将base_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());
【问题讨论】:
-
既然有
obj,为什么不直接使用呢?如果你不能在你的真实代码中,那么丑陋的演员是你唯一的手段。 -
我考虑了模板中描述的情况。我认为这种转换有时会很有用。在我的问题中,我决定使用多重继承和
static_cast。 -
通过 MyItem 访问值会模棱两可!
-
是的。
int value对于链接必须是私有的。
标签: c++ pointers static-cast member-pointers pointer-conversion