乐闻世界logo
搜索文章和话题

为什么shared_ptr<void>是合法的,而unique_ptr<void>却是格式错误的?

6 个月前提问
5 个月前修改
浏览次数59

1个答案

1

在C++中,shared_ptr<void> 是合法的,而 unique_ptr<void> 却是非法的,这主要是由于两者在处理类型转换和对象析构上的不同。

1. 类型转换

shared_ptr<void> 是合法的,因为 shared_ptr 支持隐式的类型转换。使用 void 类型的智能指针可以指向任何类型的对象,这样就可以在不知道具体对象类型的情况下安全地存储指针。例如,我们可以将一个 shared_ptr<int> 转换为 shared_ptr<void>

cpp
std::shared_ptr<int> sp1 = std::make_shared<int>(10); std::shared_ptr<void> sp2 = sp1; // 隐式转换

这里,sp2 可以成功存储指向 int 类型对象的指针,但是它丧失了对对象具体类型的信息。

2. 对象的析构

unique_ptr<void> 是非法的,主要因为 unique_ptr 需要在其生命周期结束时能够正确地析构所指向的对象。由于 void 类型是不完全类型,编译器无法确定如何正确地销毁 void 类型指向的对象。例如,你不能这样做:

cpp
std::unique_ptr<int> up1 = std::make_unique<int>(10); std::unique_ptr<void> up2 = std::move(up1); // 错误:无法对 void 类型进行析构

如果尝试上述代码,编译器会报错,因为 unique_ptr<void> 不能从 unique_ptr<int> 隐式转换,并且不知道如何析构 void 类型指向的内存。

结论

简而言之,shared_ptr<void> 允许存储任意类型的指针,便于类型不明确时的指针传递,而且 shared_ptr 有自己的控制块来管理对象的生命周期和引用计数,不需要知道具体的对象类型。相反,unique_ptr 需要完整的类型信息来确保对象可以被正确析构,因此 unique_ptr<void> 是不合法的。

这种设计反映了 shared_ptrunique_ptr 在使用场景和目的上的不同。shared_ptr 更适用于需要类型擦除或多个所有者的情况,而 unique_ptr 则用于需要明确所有权和类型保证的场景。

2024年6月29日 12:07 回复

你的答案