2013-12-14 106 views
3

C++有static_castbase_class_pointer轉換爲derived_class_pointerC++轉換:有指向對象成員的指針,計算指向對象的指針

這是非常類似的操作,將object_data_member_pointer轉換爲object_pointer

我寫了函數ConvertDataMemberPtrToObjectPtr使用不安全的C類型轉換。

  • 這怎麼能以安全的方式完成?鏈接到成員必須被指定爲模板參數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()); 
+0

既然你擁有它,爲什麼不直接使用'obj'?如果你不能在你真實的代碼中,那麼醜陋的演員是你唯一的手段。 – uk4321

+0

我認爲模板中描述的情況。我認爲這種轉換有時可能有用。在我的問題中,我決定使用多重繼承和'static_cast'。 – stan5

+0

通過MyItem訪問值將不明確! –

回答

2

你正在嘗試實現是不可能的:區分成員的信息丟失。 您需要一個可以傳遞給您的轉換函數的唯一引用成員。

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

雖然這沒有意義。有對象指針,你可以直接傳遞(也許轉換爲void *);

+0

我想在'return(T *)...'中避免「不安全的C類型轉換」。在我看來,你對'printf(「\ n0x%08lX-錯誤!」...「問題的回答,但這不是我的觀點。 – stan5

+0

不 - 我正在處理你區分成員的嘗試。 –