常规指针不具备析构函数的类对象,所以常常必须手动delete来释放内存;智能指针指向的对象,在对象过期的时候,让他的析构函数删除指向的内存。这正是auto_ptr、shared_ptr、unique_ptr背后的思想。模板auto_ptr是C++98提供的解决方案,在C++11已经将其摒弃,并提供另外两种解决方案。所以auto_ptr你不要使用就行。
下图将说明auto_ptr 与常规指针在行为上的差别。就下图要说明的这一方面,auto_ptr、shared_ptr、unique_ptr用法相同
以上第三步:因为要离开函数这个局部作用域,故:指针pd会被删除,如果你用 unique_ptr 指针,也会自动那个析构
例子:
#include#include<string> #include class Report { public: Report(const std::string s):str(s) { std::cout << "对象创建" << std::endl; } ~Report() { std::cout << "对象被销毁" << std::endl; } void comment() const { std::cout << str << std::endl; } private: std::string str; }; int main() { //这里{}作用阈问题,比如ps重复声明了3次,所以括号限制作用阈 //参考: https://blog.csdn.net/aidem_brown/article/details/53069641 { std::auto_ptr ps(new Report("using auto_ptr")); ps->comment(); } { std::shared_ptr ps(new Report("using shared_ptr")); ps->comment(); } { std::unique_ptr ps(new Report("using unique_ptr")); ps->comment(); } return 0; }
cmd输出:
这三个智能指针都有一个显式 explicit构造函数,该构造函数将指针(同类型)作为参数
//智能指针赋值操作 using namespace std; shared_ptr<double> pd; double *p_reg = new double; //禁止隐式转换 //pd = p_reg; //shared_ptrpshared = p_reg; //允许显式转换 pd = shared_ptr<double>(p_reg); shared_ptr<double> pshared(p_reg);
auto_prt<string> ps (new string("hello")); auto_ptr<string> vocation; vocation = ps;
如果ps和vocation是常规指针,两个指针将指向同一个string对象。上述代码使用是错误的,因为:程序试图删除一个对象两次;
一次是ps过期的时候,另一次是vocation过期的时候。要避免这个问题,有如下解决方案:
再举一例【auto_ptr错误使用】:
#include#include<string> #include int main() { using namespace std; auto_ptr<string> films[5] = { auto_ptr<string>(new string("one")), auto_ptr<string>(new string("two")), auto_ptr<string>(new string("three")), auto_ptr<string>(new string("four")), auto_ptr<string>(new string("five")), }; auto_ptr<string> pwin; pwin = films[2]; for (int i = 0; i < 5; i++) { cout <<"==" <<*films[i] << endl; } cout << "--" << *pwin << endl;//报错:auto_ptr没有解除引用 _DEBUG_ERROR("auto_ptr not dereferencable"); return 1; }
cmd输出:
同时出现报错: _DEBUG_ERROR("auto_ptr not dereferencable");
报错原因:
pwin = films[2];这一句导致films[2]不再引用该字符串。在auto_ptr放弃对象的所有权后,使用
auto_ptrpwin来访问对象,当在下面for循环中,程序打印films[2]指向字符串时候,缺
发现这是一个空指针,所以报错没有解除引用。
在上述报错的程序中,使用shared_ptr代替 auto_ptr(c++11),程序便能正常运行,如下:
#include
#include
#include
int main()
{
using namespace std;
shared_ptr films[5] =
{
shared_ptr(new string("one")),
shared_ptr(new string("two")),
shared_ptr(new string("three")),
shared_ptr(new string("four")),
shared_ptr(new string("five")),
};
cout << "数组对象引用次数 = " <use_count() << endl;
shared_ptr pwin;
pwin = films[2];
cout << "数组对象引用次数 = " << pwin.use_count() << endl;
cout << "*pwin = " << *pwin << endl;
for (int i = 0; i < 5; i++)
{
cout << "==" << *films[i] << endl;
}
cout << "数组对象引用次数 = " << films->use_count() << endl;
pwin = nullptr;
cout << "数组对象引用次数 = " << pwin.use_count() << endl;
films->reset();
cout << "数组对象引用次数 = " << pwin.use_count() << endl;
return 1;
}
cmd输出如下:
这次pwin和films[2]指向同一个对象,引用计数从1变成2。