2016-08-08 11 views
1

更新:
This was a bug in wxWidgetsこれは、C++ 11互換のコンパイラを使用している場合、wxWidgets 3.1.1で修正されています。基本クラスが保護されている場合、派生クラスのアクセスはアクセス不可能


イベントハンドラをwxWidgetsのイベントに動的にバインドしようとしています。残念なことに、派生クラスが保護されていれば、動作していないようです。

最小例:残念ながら動作していないよう

// Test.h 
class Test : protected wxFrame 
{ 
public: 
    Test(); 

private: 
    void sizing(wxSizeEvent& event); 
}; 

// Test.cpp 
Test::Test() 
{ 
    Bind(wxEVT_SIZING, &Test::sizing, this); 
} 

void Test::sizing(wxSizeEvent& event) 
{ 
} 

とVisual Studio 2015で次のエラーをネットアップデート3:パブリックに継承を変更

wxWidgets\include\wx/meta/convertible.h(31): error C2243: 'type cast': conversion from 'Test *' to 'wxEvtHandler *' exists, but is inaccessible 
    wxWidgets\include\wx/event.h(335): note: see reference to class template instantiation 'wxConvertibleTo<Class,wxEvtHandler>' being compiled 
      with 
      [ 
       Class=Test 
      ] 
    wxWidgets\include\wx/event.h(3568): note: see reference to class template instantiation 'wxEventFunctorMethod<EventTag,Test,EventArg,EventHandler>' being compiled 
      with 
      [ 
       EventTag=wxEventTypeTag<wxSizeEvent>, 
       EventArg=wxSizeEvent, 
       EventHandler=Test 
      ] 
    Test.cpp(78): note: see reference to function template instantiation 'void wxEvtHandler::Bind<wxEventTypeTag<wxSizeEvent>,Test,wxSizeEvent,Test>(const EventTag &,void (__cdecl Test::*)(EventArg &),EventHandler *,int,int,wxObject *)' being compiled 
      with 
      [ 
       EventTag=wxEventTypeTag<wxSizeEvent>, 
       EventArg=wxSizeEvent, 
       EventHandler=Test 
      ] 

はそれを動作なります:

class Test : public wxFrame 
  1. 継承が保護されているときに変換にアクセスできないのはなぜですか?
  2. 私はwxFrameを世界に公開するのではなく、Testクラスを派生するクラスだけを公開したいと思います。それでも、イベントハンドラを動的にバインドできる状態でこれを行うことはできますか?
  3. あなたは、次を使用してこの問題を回避することができ
+2

'Bind()'とは何ですか? – Barry

+1

保護された継承がなぜあなたのために機能すると思いますか?それはできません。 C++のOOフレームワークは公開継承に依存しています。 –

+1

@Barry Bindは、指定されたイベント(この場合はSIZING)が実行されるたびに、呼び出されるメソッドをバインドするメソッドです。詳細については、http://docs.wxwidgets.org/trunk/overview_events.html#overview_events_bindを参照してください。 – tambre

答えて

1

Bind(wxEVT_SIZING, std::bind(&Test::sizing, this, std::placeholders::_1)); 

コンパイル最小限のサンプル:エラーがから来ているので、これは実際にコードを扱うwxWidgetsのイベントで、欠陥のように見える

#include <wx/wx.h> 
#include <functional> 
using namespace std::placeholders; 

class Test : protected wxFrame 
{ 
public: 
    Test(); 

private: 
    void sizing(wxSizeEvent& event); 
}; 
Test::Test() 
{ 
    Bind(wxEVT_SIZING, std::bind(&Test::sizing, this, _1)); 
} 

void Test::sizing(wxSizeEvent& event) 
{ 
} 

class MyApp: public wxApp 
{ 
public: 
    virtual bool OnInit(); 
}; 
class MyFrame: public wxFrame 
{ 
public: 
    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); 
private: 
}; 
wxIMPLEMENT_APP(MyApp); 
bool MyApp::OnInit() 
{ 
    MyFrame *frame = new MyFrame("", wxPoint(50, 50), wxSize(450, 340)); 
    frame->Show(true); 
    return true; 
} 

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) : wxFrame(NULL, wxID_ANY, title, pos, size) 
{ 
    Test* test = new Test(); 
} 
1

チェックはによって行われ、TestwxEvtHandlerから派生しているかどうかを決定します(ここでは公にしません)。

私が推奨できる最も簡単な修正は、このチェックをバイパスする一時的なラムダを使用することです。これは動作します(もちろん、C++ 11を使用している場合)。

#include <wx/frame.h> 

class Test : protected wxFrame { 
public: 
    Test() { Bind(wxEVT_SIZING, [=](wxSizeEvent& e) { sizing(e); }); } 

private: 
    void sizing(wxSizeEvent&) { } 
}; 
関連する問題