2016-11-14 74 views
0

我針對需要靜態回調函數的外部庫進行編程。我將我的回調函數聲明爲static,但隨後我鬆散地訪問了我想用此回調函數修改的對象屬性。從靜態方法訪問對象的屬性

.h 
static void selCallback(void* userData, SoPath* selPath); 

.cpp 
void MyClass::selCallback(void* userData, SoPath* selPath) { 
    classProperty = 3; 
} 

有沒有辦法如何創建一個靜態回調,同時能夠訪問我當前的對象屬性?我使用的庫是openInventor庫。回調佈線UP是用下面的代碼來完成:

SoSelection *selNode = new SoSelection; 
selNode->addSelectionCallback(MyClass::selCallback); 
+0

'userData'可被保留用於此目的。要檢查,但'MyClass * obj = static_cast (userData)'可以讓你訪問'obj-> classProperty'。您應該檢查回調函數的調用,以瞭解對象是否以及如何傳遞。 – Franck

+1

_有沒有辦法如何創建一個靜態回調,同時能夠訪問我當前的對象屬性?_嗯..這就是爲什麼你無法從靜態上下文中訪問非靜態屬性/方法的原因。靜態方法/屬性對於類的所有實例都是常見的,並且可能創建了數百個實例。那麼,你如何決定,靜態上下文中的當前對象_是什麼?典型的做法是將一個指向對象的指針傳遞給靜態方法。然後,您可以訪問您感興趣的對象的屬性。 –

回答

1

addSelectionCallback方法有一個用於userData指針的可選參數。在那裏你應該發送對象實例,你將在你的回調中接收這個實例。

在該方法內部,您可以轉換爲正確的對象類型並執行對象實例的實際工作。

例如:

void MyClass::selCallback(void* userData, SoPath* selPath) { 
    static_cast<MyClass *>(userData)->classProperty = 3; 
} 

MyClass myInstance; 
selNode->addSelectionCallback(MyClass::selCallback, &myInstance); 
1

一般有一些地方可以指定void* userData,或者創建庫對象或註冊回調時時。您可以將其設置爲指向要從回調訪問的對象的指針。然後在回調函數中,您將void*指針返回到指向您的類的指針,並通過該指針對其進行處理。

這樣你不能使用C++智能指針,所以你必須自己照顧對象的生命週期。