将 shared_ptr<void> 转换为 shared_ptr<type> 时智能指针的行为

Behavior of Smart Pointer When Casting a shared_ptr<void> to a shared_ptr<type>

我目前正在做一个项目,该项目要求我有一个向量来存储指向相同 class 但具有不同模板值的对象的指针。我想使用 shared_ptrs 的原因我不会太深入(主要是如果我想在两个 ColumnList 之间共享一个 Column)。

我需要能够 return 从函数中转换指针(如下所示)。

所以这是一个非常简化的版本:

template <typename ColType>
class Column {
    std::vector<ColType>;
};

template <typename ...TypesOfColumns>
class ColumnList {

private:
    std::vector< std::shared_ptr<void> > columnsVector;  
    /* Needs to have a vector storing pointers to multiple Columns
       all with different template values */

public:
    template <typename ReturnType> std::shared_ptr<ReturnType> GetPointer(int index)
    {
        return std::static_pointer_cast<ReturnType>(columnsVector.at(index));
    };

};

我想知道我是否遇到了某种类型的未定义行为?它会像我希望的那样工作吗: return 强制转换的类型是否只会将 1 添加到 void 指针的强引用计数器?一个可以先于另一个被删除吗?我是否冒着内存泄漏的风险,其中一个被删除而另一个没有被删除(我怀疑是这种情况)?

一如既往,感谢大家的帮助!!!

static_pointer_cast 遵循与 static_cast 相同的规则。只要 derived 派生自 base,将指向基的指针向下转换为指向派生的指针是合法的。只要您确定 columnsVector.at(index) 包含 shared_ptr<ReturnType>(即包含起源于 shared_ptr<ReturnType>shared_ptr<void>),您所做的就是合法的。如果你不确定,你应该使用 dynamic_pointer_cast.

此外,关于内存,static_pointer_cast 的输出与输入共享相同的底层控制块,所以这样也是安全的。即使首先删除输入,输出仍将是共享资源的合法所有者,反之亦然。

IMO 最好有一个抽象列作为模板的基础 class:

struct AbstractColumn {
    virtual ~AbstractColumn() {}
    ...
};

template<typename Type>
struct Column : AbstractColumn {
    std::vector<Type> data;
};

这将提供放置泛型方法(例如转换为字符串、从字符串解析等)的地方,并且还允许您使用指向基 class 的指针而不是指向 [=11 的指针=].