C++函数指针指针转void*及placement new安全性技术问询
问题1:将指向成员函数指针或静态函数指针的指针赋值给void*是否安全?
- 核心要区分两种指针的本质:函数指针本身(比如
void (*)()或void (T::*)())是指向函数的指针,C++标准不允许直接将其转换为void*;但指向函数指针的指针(比如void (**)()或void (T::**)())是指向数据对象的指针——它指向的是存储函数指针变量的内存位置,而非函数本身。 - 根据C++标准,指向对象(包括函数指针这类对象)的指针可以安全转换为
void*,再转换回原类型时能保证值不变。所以将这类指针赋值给void*是符合标准的,不存在未定义行为,在遵循标准的平台上都是安全的。
问题2:若placement new不保证返回其第二个参数,有何替代实现方案?
标准允许用户自定义placement new重载,此时无法保证返回值等于传入的内存地址,替代方案分版本处理:
- C++20及以后:使用
std::construct_at函数。它的作用是在指定内存位置构造对象,标准明确规定它返回指向构造完成对象的指针,且该指针等于传入的内存地址转换为目标类型后的结果。用法示例:char* buf = ...; // 预分配的内存空间 MyFunc* func_ptr = std::construct_at(reinterpret_cast<MyFunc*>(buf), /* 构造参数 */); - C++20之前:直接显式调用对象的构造函数。将内存地址转换为目标类型指针后,手动触发构造初始化,比如:
也可以借助char* buf = ...; MyFunc* func_ptr = reinterpret_cast<MyFunc*>(buf); // 手动调用构造函数完成初始化 func_ptr->MyFunc(/* 构造参数 */);std::allocator的construct方法,本质也是直接触发构造逻辑,避免依赖placement new的返回值。
内容的提问来源于stack exchange,提问作者tmal
相关产品推荐
相关产品推荐

