【问题标题】:Behavior of Smart Pointer When Casting a shared_ptr<void> to a shared_ptr<type>将 shared_ptr<void> 转换为 shared_ptr<type> 时智能指针的行为
【发布时间】:2017-04-16 16:18:11
【问题描述】:

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

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

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

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 指针的强引用计数器中添加一个?可以先删除一个再删除另一个吗?我是否冒着内存泄漏的风险,其中一个被删除而另一个没有被删除(我怀疑是这种情况)?

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

【问题讨论】:

  • @cpplearner 我不同意。 “此代码有效,我可以让它变得更好吗”适合 CR。 “此代码似乎有效,但确实有效”不是。

标签: c++ pointers casting shared-ptr


【解决方案1】:

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

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

【讨论】:

  • 太棒了,第二张图真的很有帮助!非常感谢!
【解决方案2】:

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

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

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

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

【讨论】:

  • 我会明确地将虚拟析构函数移动(或至少添加)到AbstractColumn
  • @Zereges:实际上它确实应该存在,已修复。
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2014-11-09
相关资源
最近更新 更多