最近,我读了an article关于 C++ 中的惰性数据结构(尽管这个问题不是关于惰性或特定数据结构的——这只是动机)。
惰性流(列表)实现如下:
template<class T>
class Stream
{
private:
std::shared_ptr <Susp<Cell<T>>> _lazyCell;
public:
Stream() {}
Stream(std::function<Cell<T>()> f)
: _lazyCell(std::make_shared<Susp<Cell<T>>>(f))
{}
Stream(Stream && stm)
: _lazyCell(std::move(stm._lazyCell))
{}
Stream & operator=(Stream && stm)
{
_lazyCell = std::move(stm._lazyCell);
return *this;
}
bool isEmpty() const
{
return !_lazyCell;
}
T get() const
{
return _lazyCell->get().val();
}
Stream<T> pop_front() const
{
return _lazyCell->get().pop_front();
}
};
作者提到了 move 构造函数:
I also added a move constructor and a move assignment operator for efficiency.
但是,由于显式存在,不能简单地分配一个Stream
。这背后的动机是什么?
据我所知,该类仅由一个 shared_ptr
组成,可以轻松复制。在这样的类中禁止复制构造有什么好处吗?
最佳答案
shared_ptr
在内部用于共享惰性值单元格作为私有(private)实现的一部分。
但是,从用户的角度来看,它是一个不可变的对象。提供复制构造函数和赋值运算符会破坏这种不变性。
他正在为 Haskell 的不可变对象(immutable对象)的行为建模。
如果这样做是线程安全的,那么使该对象可复制是合理的,因为实际上它是一个(尽管比平常更复杂)共享实现的句柄。
但是,复制者需要了解他们复制的是共享状态的句柄,而不是状态本身。
关于c++ - 为什么不复制一个由单个 shared_ptr 组成的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39658832/