【问题标题】:How to convert a set of pointer to a set of const pointer?如何将一组指针转换为一组 const 指针?
【发布时间】:2016-07-03 02:30:12
【问题描述】:

我有一堂课Data:

class Data {
private:
    int d;
public:
    int Get() const {
        return d;
    }
    void Set(int d) {
        this->d = d;
    }
};

还有一个类Manager来管理一组Data

class Manager {
private:
    std::set<std::shared_ptr<Data>> dataSet;
public:
    const std::set<std::shared_ptr<const Data>>* GetDataSet();
};

我想使用GetDataSet()Manager 类中获取dataSet,但我不希望其他人修改集合或数据。所以我希望 GetDataSet() 的返回类型是指向一组 const 指针的 const 指针。但是,我不能在GetDataSet() 中直接return &amp;dataSet,因为std::set&lt;std::shared_ptr&lt;Data&gt;&gt; 无法转换为std::set&lt;std::shared_ptr&lt;const Data&gt;&gt;

解决问题的一种方法是复制该集合。但它有额外的费用。另一种方法是将Data类的Set()函数设为私有,让Manager类成为Data类的朋友。但它会将Data 类的所有私有字段暴露给Manager 类。

有没有更好的办法?

【问题讨论】:

  • 没有简单的方法可以做到这一点。部分原因与 std::shared_ptr 的某些设计缺陷有关。
  • 您是否有理由首先需要使用共享指针?如果您只使用 std::set 那么您可以提供对集合的 const 引用的公共访问。顺便说一句,看到共享指针的使用同时提供返回原始指针的公共方法也很奇怪。
  • @qexyn 我的Data 班级实际上很大。我在Manager 类中有两个数据集,包含几乎相同的数据集,而一组按属性a 排序,另一个按b 排序。有时我会从一组中获取前几个元素,然后从另一组中删除它们。所以我选择使用指针。
  • @qexyn 如果我将我的数据集设置为智能指针std::shared_ptr&lt;std::set&lt;std::shared_ptr&lt;Data&gt;&gt;&gt; dataSet;,并返回一个智能指针,它仍然无法转换。 std::shared_ptr&lt;const std::set&lt;std::shared_ptr&lt;const Data&gt;&gt;&gt; GetDataSet() {return std::shared_ptr&lt;const std::set&lt;std::shared_ptr&lt;const Data&gt;&gt;&gt;(dataSet);}

标签: c++ pointers casting constants containers


【解决方案1】:

我不确定,但也许 C 指针转换可能会有所帮助,使用 typedef 时会更容易。

像这样:

typedef std::set<std::shared_ptr<Data>> DataSet;
typedef const std::set<std::shared_ptr<const Data>> ConstDataSet;
class Manager {
private:
    DataSet dataSet;
public:
    ConstDataSet* GetDataSet(){
        return  (ConstDataSet*) &dataSet;
    }
};

编辑 我刚刚在 Visual Studio 10 Express 中尝试过,它成功了。

我猜它之所以有效,是因为 std::shared_ptr&lt;Data&gt;std::shared_ptr&lt;const Data&gt; 具有相同的结构。

【讨论】:

  • 它也适用于我。我尝试了return &amp;((const std::set&lt;std::shared_ptr&lt;const Data&gt;&gt;)dataSet);,但没有尝试return (const std::set&lt;std::shared_ptr&lt;const Data&gt;&gt;*)&amp;dataSet;。我认为它也应该按预期工作。但是既然有人减去了这个答案,不知道有没有不足?
  • 我猜不赞成的选民很生气,因为我没有使用return reinterpret_cast&lt;ConstDataSet*&gt;(&amp;dataSet); 这也有效... :)
【解决方案2】:

我认为一个不错的解决方案是构造并返回一个 std::vector&lt;const Data*&gt;,因为您不想与调用者共享所有权(我假设)。除非经常使用GetDataSet(),否则我认为它不会对性能产生太大影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 2017-05-15
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2013-10-20
    相关资源
    最近更新 更多