为什么要转换为空指针?
Why would you convert to a void pointer?
>我在这个问题中看到以下代码:
class CFoo
{
int a;
public:
CFoo():a(1){}
~CFoo(){}
getNum(){return a;}
};
void tfunc(void* data)
{
CFoo* foo = static_cast<CFoo*>(data);
std::cout << "Number: " << foo->getNum();
delete foo;
}
int main()
{
CFoo* foo = new CFoo;
void* dt = static_cast<void*>(foo);
tfunc(dt); // or tfunc(static_cast<void*>(food));
return 0;
}
并开始思考为什么要将指向类型的指针转换为指向 void 的指针,而不是简单地将实际指针分配给 void 指针。就像在上面的代码中调用tfunc
一样,他本可以像tfunc(&foo)
一样调用它,而不是像使用静态强制转换static_cast<void*>(foo);
那样将指针转换为 void 指针的类型,对吧?
你问题的措辞有点混乱,你实际上并不是在问为什么要转换为void*
,你是在问为什么使用显式强制转换而不是依赖隐式强制转换,即
tfunc(static_cast<void*>(food)); // explicit casting
与
tfunc(food); // implicit casting
这个问题比投void*
更普遍一些。不幸的是,C++
允许相当数量的隐含危险铸件。例如,在singed
和unsigned
之间,从较宽的整数或浮点到较窄的整数或浮点数,转换为布尔值和转换为void*
。所有这些转换都有可能在代码中静默地引入错误。c++11
在正确的方向上迈出了一小步,不允许在新的统一初始值设定项语法{}
中缩小范围,但由于向后兼容性,仍然允许所有以前的隐式强制转换。
这就是鼓励显式转换的原因。它有助于显示作者的意图。它表明转换是明确需要的,而不是在作者不知情的情况下悄无声息地发生。同样非常重要的一点是,它有助于代码审查或阅读代码时,它被标记为"这里有投射。当您查看此代码时请注意这一点">
从上面的例子中,我不明白为什么函数tfunc
的签名是void tfunc(void* data)
而不是void tfunc(class CFoo* data)
。
无论如何,将任何类型 T 的指针转换为void *
都是有效的,以后将这样的指针转换回T*
是有效的。从T*
转换可以是隐式的,而从void*
转换回T*
则需要显式转换。因此,在您的示例中,tfunc(foo)
等效于tfunc(static_cast<void*>(foo))
和tfunc(dt)
。
关于"将CFoo*
转换为void*
"这一点,有一个标准转换(参见这个 C++ 在线标准草案):
4 (1) 标准转换是内置的隐式转换 意义。第4条列举了此类转换的全部集合。
4.10 指针转换 (2) "指向 cv T 的指针"类型的 prvalue,其中 T 是对象类型,可以转换为类型的 prvalue "指向简历无效的指针"。转换非空指针的结果 指向对象类型的指针的值表示 "指向 cv void 的指针" 内存中与原始指针值相同的字节的地址。 ...
我更喜欢隐式转换而不是显式转换,因为(隐式)标准转换的内置含义完全满足要求。
在函数签名中void*
的一个用例可能是,人们想要传递不相关类型的对象,并在函数内部决定必须将其转换回哪种类型。例如,假设一个处理不同响应类型的回调的函数,并且每个响应类型可能传递不同的(类分层独立)对象:
void someCallback(int responseType, void *context) {
if(responseType == 1) {
CFoo1* foo1 = static_cast<CFoo1*>(context);
...
}
else {
CFoo2* foo2 = static_cast<CFoo2*>(context);
...
}
}
- 正在将指针转换为范围
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 运行时错误:引用绑定到类型为"int"的空指针
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- 将多映射转换为空指针,然后转换回多映射
- 为什么要转换为空指针?
- 如何将空指针转换为类数组
- 将一对包含空指针的指针强制转换为一对其他类型的指针
- 指向布尔值的空指针的隐式强制转换
- 不带类型强制转换的空指针
- 理解将结构强制转换为空指针
- 空指针常量转换为右值
- 转换std::chrono::system_clock::time_point::min()为字符串时,无效空指针错误
- 将segfault转换为空指针
- 用于类型转换空指针的类型/类的向量
- 指针算术的空指针的类型转换
- 转换为空指针后从char数组读取int值
- 将整数数组强制转换为空指针-phread_create
- 将指向结构体或内存对象的空指针强制转换为新结构体