C++ 是否有C++;懒惰的指针?

C++ 是否有C++;懒惰的指针?,c++,pointers,C++,Pointers,我需要一个类似于的共享\u 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

我需要一个类似于
的共享\u 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.
类框
{
公众:
无符号整数宽度;
无符号整数高度;
Box():宽度(50),高度(100){
};
std::向量框;
框。调整大小(100);
//此时,长方体不包含任何真实的长方体对象。
//但是当我试着进入50号盒子时,
//它将被创建。

我从来没有听说过这样的事情,但是还有很多事情我从来没有听说过。“惰性指针”如何将有用的数据放入基础类的实例中


你确定a不是你真正想要的吗?

我从来没有听说过这样的事情,但是还有很多事情我从来没有听说过。“惰性指针”如何将有用的数据放入基础类的实例中


你确定a不是你真正想要的吗?

据我所知,目前还没有这种东西的实现。但创建一个并不困难。

据我所知,目前还没有这种东西的实现。不过,创建一个并不难。

您只需花很少的努力就可以实现自己的目标

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;
模板
班级懒惰{
公众:
lazy():子(0){}
~lazy(){delete child;}
T&运算符*(){
如果(!child)child=new T;
返回*儿童;
}
//如果未设置,可能会取消对空指针的引用。。。
//但如果这是常量,还能做什么?
常量T&运算符*()常量{return*child;}
T*运算符->(){return&**this;}
常量T*运算符->()常量{return&**this;}
私人:
T*儿童;
};
// ...
库特宽度;

你只需花很少的努力就能实现自己的目标

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;
模板
班级懒惰{
公众:
lazy():子(0){}
~lazy(){delete child;}
T&运算符*(){
如果(!child)child=new T;
返回*儿童;
}
//如果未设置,可能会取消对空指针的引用。。。
//但如果这是常量,还能做什么?
常量T&运算符*()常量{return*child;}
T*运算符->(){return&**this;}
常量T*运算符->()常量{return&**this;}
私人:
T*儿童;
};
// ...
库特宽度;

使用
boost::optional
,您可以拥有这样的东西:

// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
现在,它使用
boost::optional
执行任务。它应该支持像这样的就地构造(例如
op*
):


这不需要任何复制。但是,当前的增压手册不包括操作员过载分配。然而,消息来源确实如此。我不确定这是否只是手册中的一个缺陷,或者它的文档是否被故意遗漏。因此,我会使用更安全的方法,使用
T()
进行拷贝分配

使用
boost::optional
,您可以拥有这样的东西:

// 100 lazy BigStuffs
std::vector< boost::optional<BigStuff> > v(100);
v[49] = some_big_stuff;
现在,它使用
boost::optional
执行任务。它应该支持像这样的就地构造(例如
op*
):


这不需要任何复制。但是,当前的增压手册不包括操作员过载分配。然而,消息来源确实如此。我不确定这是否只是手册中的一个缺陷,或者它的文档是否被故意遗漏。因此,我会使用更安全的方法,使用
T()
进行拷贝分配

因为稀疏矩阵满足类似(尽管不完全相同)的需求。请注意,海报的示例显示了一个“惰性指针”向量;这听起来很像稀疏矩阵,因为稀疏矩阵满足了类似(尽管不完全相同)的需求。请注意,海报的示例显示了一个“惰性指针”向量;这听起来很像一个稀疏矩阵。包含子元素是有意义的,因为您甚至可以使用boost::optional代替子元素指针。使用boost::optional意味着您可以从其堆栈分配中获益。然后不使用堆,这个自定义解决方案需要一个复制构造函数。让child可变如何,这样const方法就不会返回0?@ephemient:我同意Thomas的观点,即应该声明
child
。这正是
mutable
设计用来解决的问题。我的意思是,如果你想要纯常量,那么像这样的类无论如何都是一个糟糕的设计,在这种情况下,我甚至认为它是不正确的!将child包含为auto_ptry是有意义的,您甚至可以使用boost::optional而不是child指针。使用boost::optional意味着您可以从其堆栈分配中获益。然后不使用堆,这个自定义解决方案需要一个复制构造函数。让child可变如何,这样const方法就不会返回0?@ephemient:我同意Thomas的观点,即应该声明
child
。这正是
mutable
设计用来解决的问题。我的意思是,如果你想要纯常量,那么像这样的类无论如何都是一个糟糕的设计,在这种情况下,我甚至认为它是不正确的
vectorv(100)
将使用100*sizeof(Box),这可能没问题,但OP可能不想为未分配的框使用内存。由于OP没有描述更多的需求,我们不知道……对,我不想在未分配的对象上浪费空间。
vectorv(100)
将使用100*sizeof(Box),这可能没问题,但OP可能不想为未分配的框使用内存。因为OP没有描述更多的需求,我们不知道……对,我不想在未分配的对象上浪费空间。