有 C++ 惰性指针吗?
Posted
技术标签:
【中文标题】有 C++ 惰性指针吗?【英文标题】:Is there C++ lazy pointer? 【发布时间】:2009-05-18 15:00:38 【问题描述】:我需要一个类似shared_ptr
的对象,但是当我尝试访问它的成员时它会自动创建一个真实的对象。
例如,我有:
class Box
public:
unsigned int width;
unsigned int height;
Box(): width(50), height(100)
;
std::vector< lazy<Box> > boxes;
boxes.resize(100);
// at this point boxes contain no any real Box object.
// But when I try to access box number 50, for example,
// it will be created.
std::cout << boxes[49].width;
// now vector contains one real box and 99 lazy boxes.
是否有一些实现,或者我应该自己编写?
【问题讨论】:
【参考方案1】:自己动手做起来很轻松。
template<typename T>
class lazy
public:
lazy() : child(0)
~lazy() delete child;
T &operator*()
if (!child) child = new T;
return *child;
// might dereference NULL pointer if unset...
// but if this is const, what else can be done?
const T &operator*() const return *child;
T *operator->() return &**this;
const T *operator->() const return &**this;
private:
T *child;
;
// ...
cout << boxes[49]->width;
【讨论】:
将 child 包含为 auto_ptr 是有意义的 您甚至可以使用 boost::optionalchild
声明为 mutable
。这正是mutable
旨在解决的问题。我的意思是,如果你想要纯常量,那么这样的类无论如何都是一个糟糕的设计,在这种情况下,我什至认为它是不正确的!【参考方案2】:
使用boost::optional
,你可以有这样的事情:
// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
将构造 100 个lazy's 并将一个真正的some_big_stuff
分配给v[49]
。 boost::optional
将不使用堆内存,但使用placement-new 在堆栈分配的缓冲区中创建对象。我会像这样围绕boost::optional
创建一个包装器:
template<typename T>
struct LazyPtr
T& operator*() if(!opt) opt = T(); return *opt;
T const& operator*() const return *opt;
T* operator->() if(!opt) opt = T(); return &*opt;
T const* operator->() const return &*opt;
private:
boost::optional<T> opt;
;
这现在使用boost::optional
来做事。它应该支持像这样的就地构造(op*
上的示例):
T& operator*() if(!opt) opt = boost::in_place(); return *opt;
这不需要任何复制。但是,当前的 boost 手册不包括该赋值运算符重载。然而,消息来源确实如此。我不确定这是否只是手册中的一个缺陷,或者是否故意遗漏了它的文档。所以我会使用更安全的方式来使用T()
进行复制分配。
【讨论】:
vector<LazyPtr<Box> > v(100)
将使用 100*sizeof(Box),这可能没问题,但也许 OP 不想为未分配的 Box 使用内存。由于OP没有描述更多的要求,我们不知道......
对,我不想在未分配的对象上浪费空间。【参考方案3】:
我从来没有听说过这样的事情,但话说回来,我从来没有听说过很多事情。 “惰性指针”如何将有用的数据放入底层类的实例中?
您确定 sparse matrix 不是您真正想要的吗?
【讨论】:
因为稀疏矩阵可以满足类似(尽管不相同)的需求。请注意,海报的示例显示了“惰性指针”的向量;这听起来很像一个稀疏矩阵。【参考方案4】:据我所知,目前还没有这种事情的实现。不过创建一个并不难。
【讨论】:
以上是关于有 C++ 惰性指针吗?的主要内容,如果未能解决你的问题,请参考以下文章