我想将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;
};
此选项没有终身问题。但是,我不确定这是否是最好的做法。那么,我们应该怎么做呢?
答案 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
向量中的move
或A
将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};