作为Class containing auto_ptr stored in vector的后续内容,我相信没有明确的结论是,使用auto_ptr
成员作为容器元素的类是可以的,只要两者复制构造和复制赋值是用户定义的(以便不调用auto_ptr
的复制构造函数和复制赋值。是否存在违反标准库要求的任何?
请告诉我以下是否有任何问题,因为我想以惯用方式开始这样做:
#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
被实例化时,它的析构函数必须在Y
上调用delete,因此Y
不能是不完整的类型。我想在类X
管理多个资源(有几个auto_ptr
成员)的情况下,必须权衡RAII的值。有什么想法吗?
我认为这种技术总体来说很棒,为类可能必须构造/破坏/复制潜在的多个资源(单一责任主体)的类消除了许多棘手的代码。我只是想知道auto_ptr
是否符合此目的,或者由于某些微妙的语言/标准库要求而无法在此处工作。
请注意我知道其他类型的智能指针,但我正在实现库接口,我不想对我的客户端强加Boost或TR1的任何要求。任何有关使用auto_ptr
的讲座都将被低估!
答案 0 :(得分:1)
我认为您已在std::auto_ptr
之上实施了 克隆智能指针 。我不确定这是否值得麻烦,因为你在愚蠢的指针之上实现一个并不是很远。
但据我所知,这里没有错误。 (当然,这样说会让我在发布此帖后5分钟指出一个明显的缺陷......)
答案 1 :(得分:1)
当析构函数超出范围时使用auto_ptr 会导致未定义的行为。 MSVC警告它。海湾合作委员会没有。
您可以使其工作,但前提是未将析构函数定义为内联函数。
unique_ptr和scoped_ptr解决了这个问题。至少在那些情况下你无法编写未定义的代码。
答案 2 :(得分:-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(){}