void*可接收任何指针类型,但转回原类型必须用static_cast显式转换;它不携带类型信息,不可解引用;作函数参数时需确保所指对象生命周期足够长。

void* 能接住任何指针,但必须显式转换
直接把 int*、char* 或自定义类型的指针赋给 void* 是合法的,C++ 允许隐式转为 void*(C++11 起仍保留该规则)。但反过来——从 void* 拿回原类型指针时,必须用 static_cast 显式还原,否则编译失败。
常见错误是写成 int* p = vp;(vp 是 void*),这在 C++ 中不被允许;而 C 语言里可以隐式转回,这点容易踩坑。
-
void*本身不携带类型信息,不能解引用(*vp会报错) - 传参时,函数形参声明为
void*即可接收任意对象地址,比如pthread_create的第四个参数 - 若原始指针指向栈上局部变量,传出去后原作用域结束,
void*就成了悬空指针——这点和普通指针一样,但更容易被忽略
函数参数中传递 void* 的典型写法
比如实现一个通用内存拷贝函数,或封装系统调用:
void process_data(void* data, size_t size) {
// 假设调用方保证 data 实际是 int 数组
int* arr = static_cast<int>(data); // 必须 cast
for (size_t i = 0; i <p>关键点:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill2659" title="C++"><img
src="https://img.php.cn/upload/skill/000/000/081/178927213426672.jpg" alt="C++" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="overflowclass">C++</a>
<p class="overflowclass">"空空如也"</p>
</div>
<a rel="nofollow" href="/xiazai/skill2659" title="C++" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>调用方负责告诉被调函数“这个 <code>void*</code> 真实是什么类型”,通常靠额外参数(如 <code>size</code>、<code>type_id</code>)或文档约定</li>
<li>如果类型不匹配(比如把 <code>double*</code> 当作 <code>int*</code> 强转),行为未定义,可能读错字节、触发 SIGBUS 或静默出错</li>
<li>别用 <code>reinterpret_cast</code> 替代 <code>static_cast</code>:前者绕过类型安全检查,仅适用于低层位模式操作(如对齐计算)</li>
</ul>
<h3>struct 成员含 void* 时怎么安全存取</h3>
<p>常用于实现泛型容器或回调上下文,例如:</p>
<pre class="brush:php;toolbar:false;">struct task_ctx {
void* user_data;
void (*callback)(void*);
};
使用时需严格配对:
- 存入前确保生命周期足够长(堆分配或全局对象优先)
- 回调函数内立刻用
static_cast转回原类型,不要缓存void*长期使用 - 若要支持多种类型,建议加一个
enum type_tag字段辅助判断,避免强转错误 - C++20 后更推荐用
std::any或std::variant替代裸void*,类型安全且自带析构管理
为什么 reinterpret_cast 有时必要
绝大多数情况直接赋值就行,但有两个例外必须用 reinterpret_cast:
- 把函数指针转成
void*(标准禁止函数指针与对象指针互转,但 POSIX 要求dlsym返回void*,此时需reinterpret_cast) - 对非标准布局类型(含虚函数、多重继承)取地址后转
void*,若后续按 POD 方式解释内存,需明确告知编译器这是位重解释 - 普通对象指针 →
void*不需要reinterpret_cast,用static_cast或隐式转换即可
真正难的不是怎么转,而是谁负责知道原始类型、什么时候释放内存、以及多线程下 void* 指向的对象是否还在。这些逻辑一旦脱钩,调试起来比类型转换本身麻烦得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










