回调的缺陷
Callback's flaws
From: 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++中,或者我在错误的树上吠叫?
嗯,假设Qt希望您给他一个回调,该回调以指向QString的指针作为参数:您的c++类型定义为回调将看起来像:
typedef int (*callback_function)( QString *string);
现在,当这个回调被调用时,你永远不能确定传递的参数真的是一个QString:在c++中,这个语句是有效的,很可能会使你的回调崩溃:
int MyCallback( QString *string )
{
if(string)
printf("QString value: %sn", string->toAscii());
}
/* in another function */
char *badQstring = "Booohhh";
MyCallback( (QString *)badQstring ); // crash, badQstring is not a QString!
由于c++允许强制类型转换,因此您永远无法确定实际传递给回调的是什么类型。但是,这个语句对任何函数都有效,即使不是回调函数。
请以sqlite3_exec()
为例。它的void*
参数是一个指向"上下文对象"的指针,该对象在调用回调函数时传递给回调函数。这完全取决于用户确定这个void*
指向他所期望的类型。
sqlite3_exec()
,并将其隐式转换为void*
,然后当您的回调被调用时,您必须将其从void*
强制转换回来,如果您将其强制转换为错误的类型,则没有人捕获您。
这是一个指向函数的指针,有些编译器在运行时不会检查是否存在指针指向具有不同参数的函数的情况
相关文章:
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 如何使用 Node-addon-API 实现 node-nan 回调
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 访问类C++ C 样式回调
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 在C++中实现回调
- 回调的缺陷