将std :: vector v传递给需要在相应实例的整个生命周期内访问v的类的ctor

时间:2015-08-07 13:03:49

标签: c++ c++11

我想将std::vector<double> v传递给类A的构造函数,该类需要在相应实例的整个生命周期内访问v。由于v被认为是巨大的,我不想复制v

我们可以执行以下操作:选项1

class A
{
public:
    A(std::vector<double> const& v)
        : m_v(v)
    { }

private:
    std::vector<double> const& m_v
};

如果我们可以保证引用的v对象的生命周期至少与A的相应实例的生命周期一样长,那么这可能是一个合适的选项。但我们不太可能保证这一点。

选项2:

class A
{
public:
    A(std::shared_ptr<std::vector<double>> v)
        : m_v(v)
    { }

private:
    std::shared_ptr<std::vector<double>> m_v;
};

此选项没有终身问题。但是,我不确定这是否是最好的做法。那么,我们应该怎么做呢?

4 个答案:

答案 0 :(得分:3)

如果向量必须在A的实例的整个生命周期中保持活着,我会选择2,否则我会考虑std :: weak_ptr&lt; std :: vector&lt; double&gt;&gt;

答案 1 :(得分:3)

  • 如果您不能保证引用的v对象的生命周期至少与相应A实例的生命周期一样长,

  • 如果您不想复制v

然后shared_ptr即可。 被认为是最佳做法。

例如,请参阅Guru Of The Week 91, by Herb Sutter

注意:shared_ptr将延长v的生命周期,而weak_ptr赢了 - 您可能会失去v(以安全的方式)在A的生命中。您是否需要其中一个取决于您的使用案例。

答案 2 :(得分:2)

  

如果我们能够保证引用的v对象的生命周期至少与A的相应实例的生命周期一样长,那么这可能是一个合适的选择。但是我们不太可能保证这一点。

(强调我的)建议在设计上还有更多工作要做。您的类可以控制向量的生命周期,也可以依赖于它。这是什么?这应该在界面的任何文档和描述中清楚。

IF 你规定A取决于可用的向量,那么在界面中要求它是可以接受的:

A::A(const std::vector<double>& v)  // Demand that v outlives A
: _v(v) {}

IF 您规定A将与其他对象共享该向量,然后在界面中请求它:

A::A(std::shared_ptr<const std::vector<double>> pv) // demand shared ownswership
: _pv(std::move(pv)) {}

IF 您规定A实际上会控制向量的生命周期(之后拥有它),然后move向量中的moveA将unique_ptr改为// call with auto a = A(std::move(v)); // or auto a = A(std::vector<double>(...)); A::A(std::vector<double> v) // demand ownership or copy : _v(std::move(v)) {} // or A::A(std::unique_ptr<const std::vector<double>> pv) // demand ownership : _pv(std::move(pv)) {}

phpize
./configure
make

“最佳实践”的一部分是使用接口定义为客户提供保证并提出要求。

答案 3 :(得分:0)

  

但是,我不确定这是否是最好的做法。那么,我们应该怎么做呢?

auto make_huge_vector()
{
    return std::make_shared<std::vector<double>>( /* ... */ );
}

当前的最佳实践(如果需要,强制延长矢量的生命周期):

class A
{
public:
    A(std::shared_ptr<std::vector<double>> v): v_{ std::move(v) } {}
private:
    std::shared_ptr<std::vector<double>> v_;
};

// client code:
auto v = make_huge_vector();
A a{v};