分类:c++| 发布时间:2015-10-08 07:48:00
如何将一个智能指针对普通指针的所有权转移给另一个智能指针呢? 你可能首先想到:
bool transfer_ownership()
{
smart_ptr<int> int_p(new int(3));
if (!int_p)
return false;
smart_ptr<int> int_p2(int_p.release());
// do some thing
return true;
}
以上例子是没问题的,但是繁琐了点。 通过实现拷贝构造函数以及重载 operator= 可以更方便的转移所有权。
template<typename T>
class smart_ptr
{
public:
explicit smart_ptr(T *p = 0): p_(p) {}
smart_ptr(smart_ptr<T> &rhs): p_(rhs.release()) {}
~smart_ptr() {
clean();
}
void reset(T *p) {
if (p_ == p)
return;
clean();
p_ = p;
}
T* get() {
return p_;
}
T* release() {
T* tmp = p_;
p_ = 0;
return tmp;
}
smart_ptr<T>& operator= (smart_ptr<T> &rhs) {
if (this != &rhs) {
this->reset(rhs.release());
}
return *this;
}
bool operator! () const {
return !p_;
}
T& operator* () const {
return *p_;
}
T* operator-> () const {
return p_;
}
void clean() {
if (p_) {
delete p_;
p_ = 0;
}
}
private:
T *p_;
};
bool transfer_ownership()
{
smart_ptr<int> int_p(new int(3));
if (!int_p)
return false;
smart_ptr<int> int_p2(int_p);
// or:
// smart_ptr<int> int_p2;
// int_p2 = int_p;
// do some thing
return true;
}
到目前为止,我们实现的 smart_ptr 的行为其实跟 auto_ptr 是基本一样的, 因此虽然本节针对的是 auto_ptr 但是同时适用于我们实现的 smart_ptr 。
在 STL 容器中保存 auto_ptr 是不被允许的。 STL 容器中的元素必须是可拷贝以及可赋值的,同时赋值前后的两个元素必须是逻辑独立的。
auto_ptr 不能用于容器的原因是:
void some_func()
{
auto_ptr<int> p1(new int(3));
auto_ptr<int> p2;
p2 = p1;
}
在执行 p2 = p1 之后,p1.get() 为 NULL 也就是说赋值操作会影响到右值。 不满足赋值前后的两个元素必须是逻辑独立的条件。