将std::shared_ptr<char>转换为std::shared_ptr<unsigned char>

4

有没有一种好的方法将 shared_ptr<char> 转换为 shared_ptr<unsigned char>

我想到了以下方法,但看起来不太干净。

int main(int argc, char** argv)
{
    std::shared_ptr<char> p1 = std::make_shared<char>();

    std::shared_ptr<unsigned char> p2 = std::shared_ptr<unsigned char>(
        reinterpret_cast<unsigned char*>(p1.get()),
        [p1](unsigned char*) {});
}

我最初不理解lambda捕获,并认为存在错误,但经过深思熟虑,我认为没有问题。实际上,这似乎是一种更繁琐但更通用的解决方案,比reinterpret_pointer_cast更好。事实上,reinterpret_pointer_cast似乎是一个坏主意。它只消除了重新解释一级指针的情况。如果有多级指针(例如,***char),它会崩溃并创建需要更多语义技巧的情况。而lambda捕获可以在这种情况下更统一地应用。 - grovkin
1个回答

6

针对你正在做的事情,有一个现成的函数可以使用,reinterpret_pointer_cast

std::shared_ptr<unsigned char> p2 =
    std::reinterpret_pointer_cast<unsigned char>(p1);

生成的指针与原始指针共享所有权。

相比之下,您自己的代码最终会有两个独立的所有权组。如果原始组先死亡,则您的新指针将被悬空!

如果使用别名构造函数,则可以同时使用p1.get()并与原始指针共享所有权。事实上,这些强制转换帮助程序就是这样实现的(请参见链接):

std::shared_ptr<unsigned char> p2(p1, reinterpret_cast<unsigned char*>(p1.get()));

这将创建一个共享指针,该指针与p1共享所有权,但存储作为第二个构造函数参数给定的值。


你有reinterpret_pointer_cast的实现吗?我在我的编译器中找不到它。 - tcb
答案没有提到的是:如果你需要这样做,那么很可能出了什么问题 - Lightness Races in Orbit
@tcb:只需点击链接,你就会发现这是C++11的一个特性。现在你可以去查找一下你的编译器是否支持这个C++11特性之一。有些人会告诉你:“如果你的编译器没有所有的C++11特性,那么你就是某种中世纪的白痴”,但这些人是错的;我们实际在使用C++而不仅仅是业余爱好者闲聊时,通常会被困在胚胎期的C++11上,如果我们很幸运的话,所以我支持你 ;) - Lightness Races in Orbit
该链接包含使用别名构造函数的可能实现,如果您没有此功能(并且不想通过 void * 和返回来回去),我可以在此处重现它。 - Kerrek SB
@KerrekSB:这种情况经常发生 ^_^ - Lightness Races in Orbit
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接