我正在尝试使用std::shared_ptr
和std::weak_ptr
来处理对象。场景是这样的:
我有类channel
的对象,它派生自抽象类abstract::channel
(具有纯虚函数)。我有一个包含共享指针(channelContainer
)到std::vector
对象的容器std::shared_ptr
(channel
)。
现在,我有一个deque (std::deque)
包含(std::weak_ptr)
中每个对象的弱指针channelContainer
。让我们说出这个deque freeChannelQueue
。
所以我们说:
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'
}
我对&#39;如何将对象的引用转换为弱指针特别感兴趣?&#39;
答案 0 :(得分:9)
你不能
将对象的引用转换为弱指针
你可以使用赋值=
从共享指针创建一个弱指针
e.g。
std::shared_ptr<abstract::channel> get_free_channel();
然后
bool release_channel(std::shared_ptr<abstract::channel> ch)
{
std::weak_ptr<abstract::channel> weak_ch = ch;
//...
}
注意一生 - shared_ptr会在指向它们的弱指针之前消失吗?
答案 1 :(得分:1)
get_free_channel()
,那么您的声明会返回对对象的引用,但是它们无法保证它的生命周期包含它们的使用。 可能无关紧要取决于您从中调用函数的客户端代码,但您可能希望返回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..
}
关于“释放”......
bool release_channel(abstract::channel& ch) {
//This should convert 'ch' to a std::weak_ptr (or std::shared_ptr) and push it to 'freeChannelQueue'
}
原样,只有在搜索channelContainer
找到对象然后从那里获取weak_ptr或shared_ptr时才可以这样做。再次 - 您应该更改原型,以便直接接收shared_ptr
或weak_ptr
,锁定空闲队列,然后将智能指针推到....
总而言之,如果不了解管理通道生命周期的方式,以及各种线程如何尝试使用对象和队列,很难给出有用的建议。我希望上述内容有所帮助,即使只是在提出一个更精确的问题。
答案 2 :(得分:0)
我理解你这样的问题:你有一个容器来容纳你所有的通道对象,你有第二个容器来维护你的应用程序可以使用哪些通道的顺序。然后,您希望接口返回对客户端的下一个空闲通道的引用,并在客户端完成后将通道释放回容器。
要获取对通道的引用,可以使用lock从weak_ptr创建shared_ptr,然后取消引用(只是不删除基础对象!)。但是,我没有看到另一种明智的方法,你需要在你的通道容器中搜索匹配的对象,并再次从匹配的shared_ptr创建一个弱指针。
我会考虑不使用weak_ptr和引用,只需坚持使用shared_ptr。由于您使用deque来维护哪些通道可用,因此您可以保留可用的shared_ptr。如果您很高兴您的客户端在完成后始终会释放频道,您可能不需要所有对象的容器,只有免费频道的双端队列 - 取决于您的整体设计。
正如其他人所说,您需要考虑频道对象的生命周期以及客户端如何使用它们。