【问题标题】:Use smart or raw pointer使用智能或原始指针
【发布时间】:2014-07-25 19:25:53
【问题描述】:

在下面的代码中,有一个Grid,其中包含points。同样,ElementFace 也有points,但我希望它们指向points 中的points

我应该使用智能指针还是原始指针。如果我使用智能指针,我应该使用std::unique_ptr 还是std::shared_ptr

struct Vector3
{
    vector <double> dim;

    Vector3 ()
    {
        dim.resize(3);
    }
};

struct Element
{
    vector <Vector3*> points;
};

struct Face
{
    vector <Vector3*> points;
};

struct Grid
{
    vector <Vector3> points;

    vector <Element> elms;
    vector <Face> faces;
};    

【问题讨论】:

  • 视情况而定 >:] 例如GridElement 的生命周期是多少? points 是否在某个时候从Grid 中删除,但仍需要从Element 访问?等等
  • 还有,网格的矢量是否被调整大小。
  • Vector3 包含什么?
  • @dyp:Grid可能会在程序执行过程中被删除。
  • @PeteKirkham:我从数据文件中读取了Grid.points 的大小。

标签: c++ pointers c++11 vector


【解决方案1】:

Here 你指定的前提是ElementFace 对象在Grid 对象中创建,容器的元素引用相同的Grid 容器,因此这三个对象的生命周期容器(pointselmsfaces)是相同的。

现在你必须考虑两种情况。

半不可变points

在这种情况下,points 保证永远不会使对其元素的引用无效(例如,它永远不会被修改)。在这里你不需要任何智能指针,你可以使用一个简单的std::reference_wrapper如下:

struct Vector3
{
    std::vector<double> dim;
    Vector3 () : dim(3) {}
};

template<class Type>
using ref_vec = std::vector<std::reference_wrapper<Type>>;

struct Element { ref_vec<Vector3> points; };
struct Face    { ref_vec<Vector3> points; };

struct Grid
{
    std::vector<Vector3>  points;
    std::vector<Element>  elms;
    std::vector<Face>     faces;
};

另一种解决方案,不等同于您的示例(elmsfaces 无法直接访问 Vector3 对象)可能是使用索引:

struct Vector3
{
    std::vector<double> dim;
    Vector3 () : dim(3) {}
};

struct Grid
{
    struct Element { std::size_t point_indices; };
    struct Face    { std::size_t point_indices; };

    std::vector<Vector3>  points;
    std::vector<Element>  elms;
    std::vector<Face>     faces;
};

也就是说,您存储points 的索引。

可变points

如果对points 执行的操作可以使引用无效,那么您可能需要考虑另一个不会使元素的引用/指针/迭代器无效的容器。

例如std::deque保证容器开头和结尾删除/插入引用的有效性。

一旦您选择了正确的容器,您就可以应用与上述相同的想法。

【讨论】:

  • 由于reference_wrapper没有默认构造函数,第一个案例会编译吗?
  • @Shibli,It definitely will。没有创建 std::reference_wrapper 对象。
猜你喜欢
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多