我收到以下警告:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
这是因为我需要将成员函数而不是普通函数作为参数传递。但程序运行正常。
我想禁用此警告(Wno-bad-function-cast不适用于C ++)或实现传递成员函数的其他方法。
答案 0 :(得分:16)
否即可。严肃对待此警告。您应该更改代码以处理此方案。
成员函数(void (MyClass::*)(byte)
)和普通函数指针(void (*)(byte)
)的指针完全不同。 See this link。你不能像那样抛弃它们。它会导致未定义的行为或崩溃。
请看这里,它们有何不同:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
现在您可能会觉得,foo(byte)
和MyClass::foo(byte)
具有相同的签名,那么为什么它们的函数指针不相同。这是因为,MyClass::foo(byte)
在内部被解析有点为,
void foo(MyClass* const this, byte);
现在你可以闻到它们之间的区别。
将指向成员函数的指针声明为
void (MyClass::*ptr)(byte) = &MyClass::foo;
您必须将此ptr
与MyClass
对象一起使用,例如:
MyClass obj;
obj.*ptr('a');
答案 1 :(得分:0)
您不能将带有两个参数的函数传递给需要一个函数的地方。无法做到,忘记它,期间,故事结束。调用者将一个参数传递给您的函数。它不知道第二个参数,它没有将它传递给你的函数,你不能让它做你想要的但是你努力尝试。
出于同样的原因,您无法传递非静态成员函数,其中需要常规函数。成员函数需要一个对象来操作。无论什么代码调用你的函数都不知道对象,没有办法将它传递给对象,并且没有办法让它使用正确的调用序列来考虑对象。
接受用户功能的接口本身就是邪恶的,而不需要用户可能希望传递给他的功能的其他数据。查看C标准库中的qsort()
函数。这是邪恶界面的一个例子。假设您要根据外部定义的某种排序规则对字符串数组进行排序。但它接受的只是一个带有两个值的比较函数。如何将该校对方案传递给比较函数?你不能,所以如果你想要它工作,你必须使用一个邪恶的全局变量,并附加所有字符串。
这就是为什么C ++已经不再传递函数指针,而是转向函数对象。函数对象可以封装您想要的任何数据。
答案 2 :(得分:-2)
此外,this可能会有所帮助
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};