【问题标题】:Make a class with an reference member copyable and moveable使具有引用成员的类可复制和可移动
【发布时间】:2019-11-09 07:47:47
【问题描述】:

我有课

class Route
{
    public:
    Route(std::vector<int> locationIds, const ILocationSource&);
    double getRouteLength() const;
    bool operator<(const Route&);

    private:
    std::vector<int> locationIds_;
    const ILocationSource& locationSource_;
};

getRouteLength() 通过遍历locationIds_ 并从ILocationSource 获取坐标来计算路线长度:

class ILocationSource
{
    public:
    virtual Location getLocation(size_t n) = 0;
};

struct Location
{
    double x, y, z;
}

我不想将坐标存储在 Route 中,因为 Location 大约是 int ID 的 6 倍,如果我在内存中有很多长路线,这可能很重要。

问题在于Route::locationSource_ 难以实现移动语义,因此尝试在std::vector&lt;Route&gt; 上调用std::sort() 会报错。

我猜,简单的解决方案是将locationSource_ 更改为指向 const 的指针,但我想知道是否有人能看到更好的解决方案或模式。不能选择单例,因为ILocationService 可能同时有多个实现。

【问题讨论】:

  • 请提供一个可重现的例子
  • std::reference_wrapper 的问题是我必须根据我的原始向量创建一个临时副本,并在排序后将原始副本分配给临时。
  • 我认为没有必要提供可重现的示例。我可以破解代码,直到它自己编译和工作。问题标题可能不是最好的。我真正想知道的是,是否有某种方法可以满足RouteILocation 之间的依赖关系,从而保持Route 可移动/可复制。
  • 关于你需要使用引用而不是值:对预期的内存使用做一些实际的数学运算。使用间接可能会影响性能。除非您需要更改 shared 坐标,否则 3 个双打太少了,使用副本(包装在 POD 结构中)可能要好得多。

标签: c++


【解决方案1】:

您应该只使用shared_ptr 而不是参考:

std::shared_ptr<const ILocationSource> locationSource_;

它解决了您的复制/移动问题,并且您获得了对 ILocationSource 实例的(共享)所有权,这保证了只要 Route 需要它,ILocationSource 就会一直存在。

除此之外,考虑通过 ref 或 const ref 传递 locationIds

【讨论】:

  • 我最终使用了std::shared_ptr,效果很好。谢谢你的建议。
猜你喜欢
  • 2019-08-23
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 2017-02-07
  • 1970-01-01
相关资源
最近更新 更多