我有以下代碼。在轉換爲基類後訪問派生類成員時崩潰
class BaseHandler
{
//Blank class
};
typedef void (BaseHandler::*InstantFunc)();
class MyDrivedClass: public BaseHandler
{
//Constructor
...
// Data Members
...
char *m_someMember;
...
void DoJob();
//More functions
...
}
MyDrivedClass::DoJob()
{
//accessing Work Something with 'm_someMember' data;
}
class ForCallback
{
public:
ForCallback(BaseHandler* handler, InstantFunc callback);
BaseHandler* GetHandler();
InstantFunc GetCallback();
void Handle(SProgressiveInfo info);
protected:
BaseHandler* m_handler;
InstantFunc m_callback;
};
ForCallback::ForCallback(BaseHandler* handler, InstantFunc callback):
m_handler(handler), m_callback(callback)
{
}
BaseHandler* ForCallback::GetHandler()
{
return m_handler;
}
InstantFunc ForCallback::GetCallback()
{
return m_callback;
}
void ForCallback::Handle()
{
(m_handler->*(m_callback))();
}
//thread1--
somefunction()
{
//Creating mydrivedclass.
MyDrivedClass *drived = new MyDrivedClass();
ForCallback *cBack = new ForCallback(drived, MyDrivedClass::DoJob);
//store cback in some global map
StoreInGlobalMap(cBack);
}
//Thread2---
someotherfunction
{
//Get cback from the global map
ForCallback *cBack = GetFromMap();
cback->Handle();
}
當我運行在iOS的代碼(編譯使用的Xcode)它工作正常,但是當我在Windows上運行的代碼(編譯使用Visual Studio中)我觀察了一些崩潰。
在我們處理回調函數時,我發現函數'DoJob'被調用,'MyDrivedClass'的'this'指針無效,我無法訪問'm_someMember'。我正在使用互斥體來同步線程之間的數據,並且沒有同步問題。
在調試期間,我發現在創建'ForCallback'對象時,我們傳遞'MyDrivedClass'的地址,但傳遞給'ForCallback'的構造函數的地址不同。這可能是由於派生類轉換爲基類指針
我發現的解決方法是將ForCallback的定義修改爲
ForCallback::ForCallback(void* handler, InstantFunc callback):
m_handler(()BaseHandler*)handler), m_callback(callback)
{
}
但是,這仍然是一個解決辦法。
請有人解釋在iOS(Xcode編譯)和Windows(用於編譯的Visual Studio 2015)上不同行爲的原因 什麼是適用於iOS和Windows的正確解決方案。
<<在調試期間,我發現在創建'ForCallback'對象時,我們傳遞'MyDrivedClass'的地址,但傳遞給'ForCallback'構造函數的地址不同。 >>這怎麼會發生?它只是傳遞指針,地址不會被改變。 – Balu
你的代碼不能編譯。事實上,它甚至不是任何可編譯代碼的簡化版本。請讓您的示例正確編譯,或者使用[this](http://pastebin.com/0mmpfDLJ)代替。 – stgatilov
基地應該有一個虛擬析構函數 –