C++ shared_ptr 和 weak_ptr 转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17522020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
shared_ptr & weak_ptr conversions
提问by user2559933
I am trying to juggle objects using std::shared_ptr
and std::weak_ptr
. The scenario is something like this:
我正在尝试使用std::shared_ptr
和来处理对象std::weak_ptr
。场景是这样的:
I have objects of class channel
which is derived from a abstract class abstract::channel
(with pure virtual functions). I have a container channelContainer
(std::vector
) containing shared pointers (std::shared_ptr
) to channel
Objects.
我有channel
从抽象类派生的类对象abstract::channel
(具有纯虚函数)。我有一个包含指向对象的共享指针 ( )的容器channelContainer
( std::vector
) 。std::shared_ptr
channel
Now, I have a deque (std::deque)
containing weak pointers (std::weak_ptr)
to each of the object in the channelContainer
. Lets name this deque freeChannelQueue
.
现在,我有一个deque (std::deque)
包含弱指针(std::weak_ptr)
给每个在对象的channelContainer
。让我们命名这个 deque freeChannelQueue
。
So lets say:
所以让我们说:
std::vector<std::shared_ptr<abstract::channel> > channelContainer;
std::deque<std::weak_ptr<abstract::channel > > freeChannelQueue;
//Assuming that both the containers are filled appropriately How do I go about implementeing the below functions?
abstract::channel& get_free_channel() {
//This should return a free channel object from 'freeChannelQueue' and pop the queue.
}
bool release_channel(abstract::channel& ch) {
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue'
}
I am particularly interested in the 'How to convert a reference to an object to a weak pointer?'
我对“如何将对对象的引用转换为弱指针?”特别感兴趣。
回答by doctorlove
You cannot
你不能
convert a reference to an object to a weak pointer
将对对象的引用转换为弱指针
You can make a weak pointer from a shared pointer, just using assignment =
e.g.
您可以从一个共享指针做一个弱指针,只是用分配=
如
std::shared_ptr<abstract::channel> get_free_channel();
then
然后
bool release_channel(std::shared_ptr<abstract::channel> ch)
{
std::weak_ptr<abstract::channel> weak_ch = ch;
//...
}
Watch out for lifetimes - will the shared_ptr go before the weak pointers that point to them?
注意生命周期 - shared_ptr 会在指向它们的弱指针之前吗?
回答by Tony Delroy
Is this your design? As is, there are some serious channel lifetime issues. For example - if code calls get_free_channel()
then your declaration returns them a reference to an object, but they have no way to guarantee it's lifetime encompasses their use. That mightnot matter depending on what the client code is that you're calling the function from, but you probably want to return a shared_ptr
, as in:
这是你的设计吗?照原样,存在一些严重的通道寿命问题。例如 - 如果代码调用,get_free_channel()
那么您的声明会返回对对象的引用,但它们无法保证它的生命周期包含它们的使用。这可能无关紧要,具体取决于您从中调用函数的客户端代码是什么,但您可能希望返回 a shared_ptr
,如下所示:
std::shared_ptr<abstract::channel> get_free_channel()
{
// return free channel from 'freeChannelQueue' and pop the queue
// take a scoped lock on the free queue if necessary
while (!freeChannelQueue.empty())
{
auto p_channel = freeChannelQueue.back();
freeChannelQueue.pop_back();
std::shared_ptr<abstract::channel> p = p_channel.lock();
if (p) return p;
}
// freeChannelQueue empty... throw or return nullptr etc..
}
Regarding "release"...
关于“释放”...
bool release_channel(abstract::channel& ch) {
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue'
}
As is, this is only possible if you search the channelContainer
to find the object then get your weak_ptr or shared_ptr from there. Again - you should probably change the prototype so it receives a shared_ptr
or weak_ptr
directly, locks the free queue then pushes the smart pointer on....
channelContainer
照原样,这只有在您搜索以找到对象然后从那里获取您的 weak_ptr 或 shared_ptr 时才有可能。再次 - 您可能应该更改原型,以便它直接接收 ashared_ptr
或weak_ptr
,锁定空闲队列,然后将智能指针推上....
All in all, it's hard to give you useful advice without understanding the way your channel lifetime is going to be managed, and how various threads might attempt to use the objects and queues. I hope the above helps a little, even if only in asking a more precise question.
总而言之,如果不了解通道生命周期的管理方式,以及各种线程如何尝试使用对象和队列,就很难为您提供有用的建议。我希望以上内容会有所帮助,即使只是提出更精确的问题。
回答by dwxw
I understand your question like this: you have a container to hold all of your channel objects and you have a second container to maintain an order of which channels can be used by your application. You would then like an interface to return a reference to the next free channel for your client, and when the client is finished it releases the channel back to the container.
我理解你的问题是这样的:你有一个容器来保存你所有的通道对象,你有第二个容器来维护应用程序可以使用哪些通道的顺序。然后,您希望一个接口为您的客户端返回对下一个空闲通道的引用,并且当客户端完成时,它会将通道释放回容器。
To get a reference to a channel you can use lockto create a shared_ptr from your weak_ptr and then dereference that (just don't delete the underlying object!). However, I don't see a sensible way to go the other way, you would need to search your channel container for the object that matches and create a weak pointer from the matching shared_ptr again.
要获得对频道的引用,您可以使用lock从您的 weak_ptr 创建一个 shared_ptr ,然后取消引用它(只是不要删除底层对象!)。但是,我没有看到另一种明智的方法,您需要在您的频道容器中搜索匹配的对象并再次从匹配的 shared_ptr 创建一个弱指针。
I would consider not using weak_ptr and references at all, just stick with shared_ptr. Since you use a deque to maintain which channels are available, you could instead just keep the available shared_ptr's there. If you are happy that your client will always release the channels when finished, you perhaps don't need a container for all the objects, only the deque for the free channels - depends on your overall design.
我会考虑根本不使用weak_ptr 和引用,坚持使用shared_ptr。由于您使用双端队列来维护可用的通道,因此您可以将可用的 shared_ptr 保留在那里。如果您很高兴您的客户总是在完成后释放通道,那么您可能不需要所有对象的容器,只需要空闲通道的双端队列 - 取决于您的整体设计。
As others have said, you need to consider the lifetime of your channel objects and how they are used by the client.
正如其他人所说,您需要考虑通道对象的生命周期以及客户端如何使用它们。