2011-12-06 50 views
0

運行時錯誤我有下面的類定義:造成錯誤調用約定

class IRenderable { 
public: 

    virtual void Render(wxBitmap *) = 0; 
} 

class MyClass : public wxWindow, public IRenderable { 

public: 

/* costructor, destructor etc... */ 


    void RenderBitmap(wxBitmap *bitmap) 
    { 
     // code 
    } 

} 

其中wxWindow的和wxBitmap是屬於wxWidgets的庫(編寫GUI應用的C++移植庫)類。

我使用Visual C的下面這段代碼是錯誤的:

MyClass *c = new MyClass(...); 
wxWindow *w = (wxWindow *)c; 
IRenderable *r_page = (IRenderable *)w; 
// bitmap is allocate somewhere else   
r_page->RenderBitmap(bitmap); 

,因爲我得到一個運行時錯誤:

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

這是怎麼回事?

我在做什麼是以下內容。第三方庫(wxAUI)獲取指向wxWindow的指針以管理它們。我已經sublcassed wxWindow(MyClass)添加一些特定的代碼。所以,我沒有使用MyClass對象來管理wxWindows對象。 在某些情況下,我要求wxAUI向我返回「當前」窗口的wxWindow指針,它應該是指向MyClass對象的指針。我想調用這些對象的RenderBitmap()方法,所以我需要將它轉換爲IRenderable,但得到運行時錯誤...

我沒有RTTI啓用,現在不要這樣做解決這個問題...

回答

1

的問題是在這裏:

IRenderable *r_page = (IRenderable *)w; 

w不指向一個IRenerable實例。我明白你爲什麼會這樣想,但事實並非如此。

避免繼承多個類,谷歌「鑽石繼承」和「虛擬繼承」,以便更好地理解。

C++ by default follows each inheritance path separately, so a D object would actually contain two separate A objects, and uses of A's members have to be properly qualified. If the inheritance from A to B and the inheritance from A to C are both marked "virtual" (for example, "class B : virtual public A"), C++ takes special care to only create one A object, and uses of A's members work correctly. If virtual inheritance and nonvirtual inheritance are mixed, there is a single virtual A and a nonvirtual A for each nonvirtual inheritance path to A. Please note that nonvirtual derivation of A in this case will be useless as direct access to any part of class A from class D will practically always end up with compile error.

:從 wikipedia article在鑽石問題

提取物