来自:http://doc.qt.nokia.com/4.7/signalsandslots.html
回调有两个基本缺陷: 首先,它们不是类型安全的。我们 永远不能确定 处理函数会调用 用正确的参数回调。
有人可以解释一下,在什么样的情况下,不确定论证是否正确?该声明的技术要点是什么?
编辑1 正如下面帖子中的 Gui13 所指出的,当传递char *时,QString确实会出错。但我测试了以下程序:
#include <iostream>
#include <QString>
#include <stdio.h>
typedef int (*callback_function)( QString *string);
int MyCallback( std::string string )
{
if (string.empty() == false)
std :: cout << string.length();
return 0;
}
int main ()
{
/* in another function */
char *badQstring = (char*)"Booohhh";
MyCallback( (std::string )badQstring );
}
它运作正常。这是否意味着Qt有一些问题w.r.t回调,这并不意味着上面提到的缺陷也是普通的C ++,或者我在错误的树上吠叫?
答案 0 :(得分:3)
请将sqlite3_exec()
视为一个很好的例子。它的void*
参数是一个指向“上下文对象”的指针,当调用后者时,它会传递给回调函数。这完全取决于用户确保此void*
指向他期望的类型。
例如,您需要一些复杂的类作为“上下文对象”。您将该类对象的地址传递给sqlite3_exec()
并将其隐式转换为void*
,然后当您的回调被调用时,您必须从void*
将其强制转换回来,如果没有人抓住您你把它扔错了类型。
答案 1 :(得分:3)
好吧,说Qt希望你给他一个回调,它带有一个指向QString的指针作为它的参数:你回调的C ++ typedef将如下所示:
typedef int (*callback_function)( QString *string);
现在,当调用这个回调时,你永远无法确定传递的参数是否真的是一个QString:在C ++中,这个语句是有效的,很可能会使你的回调崩溃:
int MyCallback( QString *string )
{
if(string)
printf("QString value: %s\n", string->toAscii());
}
/* in another function */
char *badQstring = "Booohhh";
MyCallback( (QString *)badQstring ); // crash, badQstring is not a QString!
由于C ++允许转换,因此您无法确定实际传递给回调的类型。 但是,即使不是回调函数,这个语句也适用于任何函数。
答案 2 :(得分:0)
它是一个指向函数的指针,有些编译器不检查在运行时是否会出现指针导致函数的参数与预期不同的情况。