【发布时间】:2019-11-23 14:43:55
【问题描述】:
如果将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 的弱指针。
【问题讨论】:
-
如果你真的需要转换回
doSomethingIfOwnerStillExist中的原始类型,我还建议使用std::variant<std::weak_ptr<SmallBox>, std::weak_ptr<BigBox>>之类的东西,因为它会管理你所做的所有ownerType跟踪自动为你。或者更好的是,正如您所提到的,使用带有doSomethingIfOwnerStillExist将使用的接口的基类。由于无论如何您都必须跟踪Object中的所有可能类型,所以我不认为将接口添加到每个类会更复杂。 -
我会查找 std::variant。对不起,我不能减少例子,我会看看我能做什么。
标签: c++ smart-pointers static-cast weak-ptr