如果基 class 受保护,则无法访问派生 class 中的转换
Conversion in derived class inaccessible if base class is protected
更新:
This was a bug in wxWidgets。如果您使用的是 C++11 兼容编译器,这已在 wxWidgets 3.1.1 中修复。
我正在尝试将事件处理程序动态绑定到 wxWidgets 中的事件。不幸的是,如果派生的 class 受到保护,它似乎不起作用。
最小示例:
// 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
]
将继承更改为 public 使其工作:
class Test : public wxFrame
- 为什么在保护继承的情况下无法进行转换?
- 我不想向世界公开 wxFrame,而只希望公开派生测试 class 的 classes。我怎样才能做到这一点,同时仍然能够动态绑定事件处理程序?
您可以使用以下方法解决此问题:
Bind(wxEVT_SIZING, std::bind(&Test::sizing, this, std::placeholders::_1));
编译的最小样本:
#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();
}
这看起来确实像是 wxWidgets 事件处理代码中的一个缺陷,因为错误来自 wxConvertibleTo
为确定 Test
是否源自 wxEvtHandler
所做的检查(这里它不公开这样做)。
我可以推荐的最简单的修复方法是使用一个临时的 lambda,它可以绕过这个检查,例如这有效(当然前提是你使用 C++11):
#include <wx/frame.h>
class Test : protected wxFrame {
public:
Test() { Bind(wxEVT_SIZING, [=](wxSizeEvent& e) { sizing(e); }); }
private:
void sizing(wxSizeEvent&) { }
};
更新:
This was a bug in wxWidgets。如果您使用的是 C++11 兼容编译器,这已在 wxWidgets 3.1.1 中修复。
我正在尝试将事件处理程序动态绑定到 wxWidgets 中的事件。不幸的是,如果派生的 class 受到保护,它似乎不起作用。
最小示例:
// 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
]
将继承更改为 public 使其工作:
class Test : public wxFrame
- 为什么在保护继承的情况下无法进行转换?
- 我不想向世界公开 wxFrame,而只希望公开派生测试 class 的 classes。我怎样才能做到这一点,同时仍然能够动态绑定事件处理程序?
您可以使用以下方法解决此问题:
Bind(wxEVT_SIZING, std::bind(&Test::sizing, this, std::placeholders::_1));
编译的最小样本:
#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();
}
这看起来确实像是 wxWidgets 事件处理代码中的一个缺陷,因为错误来自 wxConvertibleTo
为确定 Test
是否源自 wxEvtHandler
所做的检查(这里它不公开这样做)。
我可以推荐的最简单的修复方法是使用一个临时的 lambda,它可以绕过这个检查,例如这有效(当然前提是你使用 C++11):
#include <wx/frame.h>
class Test : protected wxFrame {
public:
Test() { Bind(wxEVT_SIZING, [=](wxSizeEvent& e) { sizing(e); }); }
private:
void sizing(wxSizeEvent&) { }
};