2010-06-11 75 views
1

我有一個問題,而黑客一個更大的項目,所以我做了一個simpel測試用例。如果我沒有遺漏某些東西,我的測試代碼可以正常工作,但也許它意外地工作,所以我想向您展示它,並詢問此方法是否存在任何缺陷。來自void *的Casting/dereferencing成員變量指針是否安全?

我有一個OutObj有一個成員變量(指針)InObj。 InObj有一個成員函數。我將這個成員變量對象(InObj)的地址作爲void *發送到回調函數。這個對象的類型永遠不會改變,所以在我重新調用它的原始類型並調用其中的aFunc成員函數的回調中。在這個例子中,它按預期工作,但在我正在研究的項目中卻沒有。所以我可能會省略一些東西,或者在這裏有一個陷阱,而且這是偶然的。任何意見?提前致謝。

(我在我原來的代碼中的問題是,InObj.data是垃圾)。

#include <stdio.h> 

class InObj 
{ 
public: 
int data; 
InObj(int argData); 
void aFunc() 
{ 
    printf("Inside aFunc! data is: %d\n", data); 
}; 
}; 

InObj::InObj(int argData) 
{ 
data = argData; 
} 

class OutObj 
{ 
public: 
InObj* objPtr; 
OutObj(int data); 
~OutObj(); 
}; 

OutObj::OutObj(int data) 
{ 
objPtr = new InObj(data); 
} 

OutObj::~OutObj() 
{ 
delete objPtr; 
} 

void callback(void* context) 
{ 
((InObj*)context)->aFunc(); 
} 

int main() 
{ 
OutObj a(42); 
callback((void*)a.objPtr); 
} 
+0

一目瞭然,它看起來不錯。在您的應用中定義「不起作用」。 – Stephen 2010-06-11 03:45:21

+0

您在項目中遇到的確切問題是什麼? – Canopus 2010-06-11 03:47:25

+0

我在我的原始代碼中存在的問題是InObj.data是垃圾。所以,如果這看起來不錯,我應該睡一覺,並找到我的代碼中的明顯錯誤。 – Damien 2010-06-11 03:48:09

回答

3

是的,這是安全的。

指向任何類型的指針都可以轉換爲void和返回的指針。

請注意,轉換void*是隱含的,所以您不需要轉換。

+0

所有指針都是相同的大小,幷包含相同的數據權利?這些類型只是爲了提醒你。 – 2010-06-11 03:45:19

+1

@Brendan Long:這不一定是真的。如果您有多個繼承層次結構,則指針轉換可能涉及實際修改指針以指向正確的vtbl結構。 – 2010-06-11 03:49:49

+4

@Brendan:有很多錯綜複雜的指針。指向成員的指針可能與指向對象的指針的大小不同。保證「可以工作」的事情之一是,如果你有一個指向'T'類型的對象的指針,你可以將'T *'轉換爲'void *',然後返回到'T *',原始'T *'和由此產生的'T *'將指向同一個對象。這是這個問題非常重要的規則。 – 2010-06-11 03:57:53

0

你發佈的內容應該是「安全的」,因爲像這樣的非類型安全操作可能是安全的。我會用static_cast而不是C樣式替換您的樣式,因爲static_cast不允許您在類型之間進行這種不安全的轉換。如果您嘗試使用static_cast做一些不安全的事情,編譯器會告訴您,而不是讓您猜測。

(方無關注:InObj的構造應該使用初始化而不是分配:

InObj::InObj(int argData) : data(argData) 
{ 
} 

相關問題