简体   繁体   English

shared_ptr和weak_ptr转换

[英]shared_ptr & weak_ptr conversions

I am trying to juggle objects using std::shared_ptr and std::weak_ptr . 我正在尝试使用std::shared_ptrstd::weak_ptr来处理对象。 The scenario is something like this: 场景是这样的:

I have objects of class channel which is derived from a abstract class abstract::channel (with pure virtual functions). 我有类channel对象,它是从抽象类abstract::channel (带有纯虚函数)派生的。 I have a container channelContainer ( std::vector ) containing shared pointers ( std::shared_ptr ) to channel Objects. 我有一个容器channelContainerstd::vector )包含channel对象的共享指针( std::shared_ptr )。

Now, I have a deque (std::deque) containing weak pointers (std::weak_ptr) to each of the object in the channelContainer . 现在,我有一个包含弱指针(std::weak_ptr)deque (std::deque) (std::weak_ptr)channelContainer中的每个对象。 Lets name this deque freeChannelQueue . 让我们命名这个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?' 我对'如何将对象的引用转换为弱指针?'特别感兴趣?

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 = eg 您可以使用assignment = eg从共享指针创建一个弱指针

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会在指向它们的弱指针之前消失吗?

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. 例如 - 如果代码调用get_free_channel()那么您的声明会返回对对象的引用,但是它们无法保证它的生命周期包含它们的使用。 That might not 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: 可能无关紧要取决于您从中调用函数的客户端代码,但您可能希望返回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. 这样,只有在搜索channelContainer才能找到对象然后从那里获取weak_ptr或shared_ptr时,才有可能。 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.... 再次 - 您应该更改原型,以便它直接接收shared_ptrweak_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. 我希望上述内容有所帮助,即使只是在提出一个更精确的问题。

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 lock to create a shared_ptr from your weak_ptr and then dereference that (just don't delete the underlying object!). 要获取对通道的引用,可以使用lock从weak_ptr创建shared_ptr,然后取消引用(只是不删除底层对象!)。 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. 但是,我没有看到另一种合理的方法,你需要在通道容器中搜索匹配的对象,并再次从匹配的shared_ptr创建一个弱指针。

I would consider not using weak_ptr and references at all, just stick with shared_ptr. 我会考虑不使用weak_ptr和引用,只需坚持使用shared_ptr。 Since you use a deque to maintain which channels are available, you could instead just keep the available shared_ptr's there. 由于您使用deque来维护哪些通道可用,因此您可以保留可用的shared_ptr。 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. 如果您很高兴您的客户端在完成后始终会释放频道,您可能不需要所有对象的容器,只有免费频道的双端队列 - 取决于您的整体设计。

As others have said, you need to consider the lifetime of your channel objects and how they are used by the client. 正如其他人所说,您需要考虑频道对象的生命周期以及客户端如何使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM