C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识

       常规指针不具备析构函数的类对象,所以常常必须手动delete来释放内存;智能指针指向的对象,在对象过期的时候,让他的析构函数删除指向的内存。这正是auto_ptr、shared_ptr、unique_ptr背后的思想。模板auto_ptr是C++98提供的解决方案,在C++11已经将其摒弃,并提供另外两种解决方案。所以auto_ptr你不要使用就行。

     下图将说明auto_ptr 与常规指针在行为上的差别。就下图要说明的这一方面,auto_ptr、shared_ptr、unique_ptr用法相同

C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第1张图片

以上第三步:因为要离开函数这个局部作用域,故:指针pd会被删除,如果你用 unique_ptr 指针,也会自动那个析构

 

 

C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第2张图片

 

例子:

#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输出:

C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第3张图片

 

这三个智能指针都有一个显式 explicit构造函数,该构造函数将指针(同类型)作为参数

 

//智能指针赋值操作
using namespace std;
shared_ptr<double> pd;
double *p_reg = new double;
//禁止隐式转换
//pd = p_reg;
//shared_ptr pshared = p_reg;
//允许显式转换
pd = shared_ptr<double>(p_reg);
shared_ptr<double> pshared(p_reg);

C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第4张图片

 

auto_prt<string> ps (new string("hello"));
auto_ptr<string> vocation;
vocation = ps;

如果ps和vocation是常规指针,两个指针将指向同一个string对象。上述代码使用是错误的,因为:程序试图删除一个对象两次;

一次是ps过期的时候,另一次是vocation过期的时候。要避免这个问题,有如下解决方案:

C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第5张图片

 

再举一例【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_ptr pwin来访问对象,当在下面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输出如下:

 C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识_第6张图片

这次pwin和films[2]指向同一个对象,引用计数从1变成2。

 

转载于:https://www.cnblogs.com/winslam/p/9070849.html

你可能感兴趣的:(C++ 智能指针auto_ptr、shared_ptr、unique_ptr《一》-----智能指针初识)