0

作为包含存储在 vector 中的 auto_ptr 的 Class的后续,我相信未说明的结论是可以使用具有auto_ptr成员的类作为容器元素,只要复制构造和复制分配都是用户定义的(以免调用auto_ptrs 复制构造函数和复制赋值)。这有什么违反标准库要求的吗?

请告诉我以下内容是否有问题,因为我想开始习惯性地这样做:

#include <memory>
#include <algorithm>

class Y { /* ... */ };
class Z : public Y { /* ... */ };

class X {
    public:
        X() : ap(new Z()) {}
        X(const X& other) : ap(other.ap->clone()) {}
        X& operator=(X other) { swap(other); return *this; } // any problem with swap?
        void swap(X& other) { std::swap(ap, other.ap); }
        // note no destructor necessary
    private:
        std::auto_ptr<Y> ap; // Y provides clone()
};

请注意,我意识到的一件事是,使用这种方法,Y' 类定义必须在X' 定义的范围内(而不是在使用“原始”指针时向前声明Y)。这是因为当auto_ptr被实例化时,它的析构函数必须在 a 上调​​用 delete Y,因此Y不能是不完整的类型。我想在类X管理多个资源(有多个auto_ptr成员)的情况下,这必须与 RAII 的值进行权衡。对此有什么想法吗?

我认为这项技术总体上很棒,可以消除可能必须构造/破坏/复制潜在多个资源(单一责任主体)的类的许多棘手代码。我只是想知道是否auto_ptr可以达到目的,或者由于某些微妙的语言/标准库要求而在这里不起作用。

请注意,我知道其他类型的智能指针,但我正在实现一个库接口,我不想对我的客户强加任何对 Boost 或 TR1 的要求。任何关于一般使用的讲座auto_ptr都将被否决!

4

3 回答 3

1

我认为您已经std::auto_ptr. 我不确定这是否值得麻烦,因为您离在哑指针之上实现一个并不远。

但据我所知,这没有错误。(当然,这样说会让人在我发帖 5 分钟后指出一个明显的缺陷……)

于 2010-11-23T19:50:17.577 回答
1

当析构函数超出范围时使用 auto_ptr导致未定义的行为。MSVC 对此发出警告。海湾合作委员会没有。

您可以使其工作,但前提是析构函数未定义为内联函数。

unique_ptr 和 scoped_ptr 解决了这个问题。至少对于那些您不会意外编写未定义代码的人。

于 2010-11-23T20:00:34.147 回答
-1

你真正想做什么?如果您只想在容器中放置一堆对象,这似乎是很多不必要的工作。在我看来,创建一个临时对象并让容器中的对象接管所有权不是问题

operator =()对我来说没有意义,它不是=它是交换。

X a,b;
a=b
assert(a==b) // fail!

你的认识不正确

请注意,我意识到的一件事是,使用这种方法,Y 的类定义必须在 X 的定义范围内(而不是在使用指向 Y 的“原始”指针时向前声明)。这是因为当 auto_ptr 被实例化时,它的析构函数必须在 Y 上调用 delete,所以 Y 不能是不完整的类型。

如果您为 X 定义析构函数并在 CPP 文件中实现,您可以完全合法地做

标题

class Y;
class X{
  virtual ~X();
  std::auto_ptr<Y> ap; 
};

身体

class Y{};
~X(){}
于 2010-11-23T20:00:39.080 回答