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

时间:2017-04-16 16:18:11

标签: c++ pointers casting shared-ptr

我目前正在开发一个项目,要求我有一个向量存储指向同一类但具有不同模板值的对象的指针。我想使用shared_ptrs是因为我不会太深入(主要是因为我想在两个ColumnLists之间共享一个列)。

我需要能够从函数返回一个转换指针(如下所示)。

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

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));
    };

};

我想知道我是否在这里遇到某种类型的未定义行为?它是否会像我希望的那样工作:是否会返回一个类型,只需在void指针的强引用计数器中添加一个?可以在另一个之前删除吗?我冒着内存泄漏的风险,其中一个被删除而另一个没有(我怀疑这是一个案例)?

一如既往,感谢所有的帮助!!!

2 个答案:

答案 0 :(得分:2)

static_pointer_cast遵循static_cast所遵循的相同规则。只要derived派生自base,将指针指向下传到指向派生的指针是合法的。只要您确定columnsVector.at(index)包含shared_ptr<ReturnType>(即包含来自shared_ptr<void>的{​​{1}}),您所做的就是合法的。如果你不确定,你应该使用dynamic_pointer_cast。

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

答案 1 :(得分:2)

IMO更好的是将抽象列作为模板的基类:

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

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

这将提供放置泛型方法的位置(例如转换为字符串,从字符串中解析等),并且还允许您使用指向基类的指针而不是指向void的指针。