出现智能指针的原因
常见的智能指针
1.你知道智能指针吗?智能指针的原理。
2.常用的智能指针。
3.智能指针的实现。
1答案:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,
2, 最常用的智能指针:
1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。
2) C++11引入的unique_ptr(scoped_ptr), 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。
例如:
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 编译会出错
std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.
3) C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。
4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。
智能指针的实现
Autoptr
代码:
#pragma once
template<class T>
class Autoptr
{
public:
Autoptr()
:_ptr(NULL)
{}
Autoptr(T *ptr)
:_ptr(ptr)
{}
Autoptr(Autoptr<T>& a)
:_ptr(a._ptr)
{
delete _ptr;
a._ptr = NULL;
}
~Autoptr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
Autoptr<T>& operator=(Autoptr<T>&a)
{
if (this != &a)
{
delete _ptr;
_ptr = a._ptr;
a._ptr = NULL;
}
return *this;
}
T& operator*()
{
return *_ptr;
}
T* Getptr()
{
return _ptr;
}
protected:
T *_ptr;
};
void Autoptrtest()
{
int *a = new int(5);
Autoptr<int> ap1(a);
cout << *ap1 << endl;
cout << ap1.Getptr() << endl;
Autoptr<int> ap2(ap1);
cout << *ap2 << endl;
cout << ap2.Getptr() << endl;
cout << ap1.Getptr() << endl;
Autoptr<int> ap3;
ap3 = ap2;
cout << *ap3 << endl;
cout << ap3.Getptr() << endl;
cout << ap2.Getptr() << endl;
}
Scopedptr
代码:
#pragma once
template<class T>
class Scopedptr
{
public:
Scopedptr()
:_ptr(NULL)
{}
Scopedptr(T *data)
:_ptr(data)
{}
~Scopedptr()
{
if (_ptr)
{
delete _ptr;
_ptr = NULL;
}
}
T& operator*()
{
return *_ptr;
}
T* Getptr()
{
return _ptr;
}
protected://加上protected可以防止使用者在类之外定义拷贝构造和运算符的重载函数
Scopedptr<T>(const Scopedptr<T>&sp); //不让使用者使用拷贝,可以防止拷贝,所以只声明不定义
Scopedptr<T>& operator=(const Scopedptr<T>&sp);
private:
T *_ptr;
};
void Scopedptrtest()
{
int *a = new int(5);
Scopedptr<int> ap1(a);
cout << *ap1 << endl;
cout << ap1.Getptr() << endl;
/*Scopedptr<int> ap2(ap1);
cout << *ap2 << endl;
Scopedptr<int> ap3;
ap3 = ap2;
cout << *ap3 << endl;
cout << ap3.Getptr() << endl;
cout << ap2.Getptr() << endl;*/
}
Sharedptr
代码:
#pragma once
template<class T>
class Sharedptr
{
public:
Sharedptr()
:_ptr(NULL)
, _pcount(new int(1))
{}
Sharedptr(T *ptr)
:_ptr(ptr)
, _pcount(new int(1))
{}
Sharedptr(const Sharedptr<T>& sp)
:_ptr(sp._ptr)
, _pcount(sp._pcount)
{
++(*_pcount);
}
~Sharedptr()
{
if (_ptr)
{
if (--(*_pcount)==0)
{
delete _ptr;
delete _pcount;
_ptr = NULL;
_pcount = NULL;
}
_ptr = NULL;
}
}
Sharedptr<T>& operator=(const Sharedptr<T> &sp)
{
if (this != &sp)
{
if (--(*_pcount) == 0)
{
delete _ptr;
delete _pcount;
_ptr = NULL;
_pcount = NULL;
}
_ptr = sp._ptr;
_pcount = sp._pcount;
++(*_pcount);
}
return *this;
}
private:
T* _ptr;
int *_pcount;
};
void Sharedptrtest()
{
int *a = new int(5);
Sharedptr<int> ap1(a);
Sharedptr<int> ap2(ap1);
Sharedptr<int> ap3;
ap3 = ap2;
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。