通过多重继承在一些MFC CWnd
派生对象上使用纯虚拟接口,我收到了一些警告。我认为这是由定义需要为消息映射实现的方法引起的。
warning C4407: cast between different pointer to member representations, compiler may generate incorrect code
这听起来不仅仅是一个警告,更像是可能导致堆损坏的东西。那么是否有另一种方法可以执行类似于下面的操作,这些方法不会导致MFC动态向下转换宏比平常更多?
class ISomeInterface
{
public:
virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};
class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};
BEGIN_MESSAGE_MAP(CSomeCoolWnd , CWnd)
ON_REGISTERED_MESSAGE(WM_USER_DEFINED, &CSomeCoolWnd::OnSomeRegisteredMessage)
END_MESSAGE_MAP()
我唯一想到的就是从界面中注释掉消息处理程序,并留下评论告诉消费者他们应该实现它们。但是,通过编译器错误强制执行该操作会很好,而不是让它们使用接口并在运行时从丢失的内容中获得意外结果。
答案 0 :(得分:4)
可以在文章Member Function Pointers and the Fastest Possible C++ Delegates中找到关于指针到成员值的不同表示的出色描述。实质上,所有不同的继承类型都可以要求使用不同的成员函数指针表示。这是特定于编译器的,本文讨论了许多不同的编译器(直到2005年撰写文章时)。
显然,对虚函数使用多重继承可能需要与简单的指向成员函数的表示不同。 ON_REGISTERED_MESSAGE()
中某处可能存在一个在您发布的代码中不可见的强制转换。
答案 1 :(得分:1)
尝试使用以下内容:
class ISomeInterface
{
public:
virtual LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp) = 0;
};
class CSomeCoolWnd : public CWnd, public ISomeInterface
{
public:
LRESULT OnSomeRegisteredMessage(WPARAM wp, LPARAM lp);
};
typedef void (CSomeCoolWnd::*FNMETHOD) (WPARAM, LPARAM);
FNMETHOD method = &CSomeCoolWnd::OnSomeRegisteredMessage;
BEGIN_MESSAGE_MAP(CSomeCoolWnd, CWnd)
ON_REGISTERED_MESSAGE(WM_USER_DEFINED, method)
END_MESSAGE_MAP()