如果将std::weak_ptr
与static_pointer_cast
存储在一起,引用计数是否仍然有效?
这是一个非常简单的示例(请注意SmallBox
和BigBox
类几乎完全相同):
#define OWNER_SMALLBOX 1
#define OWNER_BIGBOX 2
class Object
{
private:
std::weak_ptr<void> owner;
int ownerType;
public:
void doSomethingIfOwnerStillExist()
{
if(std::shared_ptr<void> ownerShared = owner.lock())
{
switch(ownerType)
{
case OWNER_SMALLBOX:
std::shared_ptr<SmallBox> smallBox = std::static_pointer_cast<SmallBox>(ownerShared);
break;
case OWNER_BIGBOX:
std::shared_ptr<BigBox> bigBox = std::static_pointer_cast<BigBox>(ownerShared);
break;
}//switch
}
}
Object(std::shared_ptr<void> _owner, int _ownerType)
{
owner = _owner;
ownerType = _ownerType;
}
};
class SmallBox
{
private:
std::list< std::shared_ptr<Object> > objects;
public:
static void addObject(std::shared_ptr<SmallBox> _smallBox)
{
std::shared_ptr<void> owner = std::static_pointer_cast<void>(_smallBox);
objects.push_back(std::make_shared<Object>(owner, OWNER_SMALL_BOX));
}
};
class BigBox
{
private:
std::list< std::shared_ptr<Object> > objects;
public:
static void addObject(std::shared_ptr<BigBox> _bigBox)
{
std::shared_ptr<void> owner = std::static_pointer_cast<void>(_bigBox);
objects.push_back(std::make_shared<Object>(owner, OWNER_BIGBOX));
}
};
我知道我可以使SmallBox
和BigBox
类继承自GeneralBox
类,并用void
类型替换GeneralBox
类型,但是weak_ptr
也可以指向其他几种类型,从而使继承非常庞大且笨拙。
我很好奇shared_ptr
是否仍然可以跟踪转换为void的弱指针。
答案 0 :(得分:3)
如果我正确理解了您的问题,那么您是在问std::static_pointer_cast
是否会返回std::shared_ptr
与调用它的参数共享所有权。
答案是肯定的。
owner
中的 addObject
将与addObject
的功能参数共享所有权,对象中的owner
将引用同一控制块,ownerShared
和{{1}中的smallBox
,bigBox
。
不过请注意,存储在doSomethingIfOwnerStillExist
中的shared_ptr
是完全不相关的,因为它们是通过调用objects
来初始化的,它们会创建一个新的std::make_shared
只能由Object
拥有。
如果objects
不返回与该参数共享所有权的实例,那将是毫无用处的,因为如果不这样做,它将不可避免地导致双重删除托管指针。