zoukankan      html  css  js  c++  java
  • c++11 stl 学习之 shared_ptr

    shared_ptr
    智能指针 shared_ptr 的声明初始化方式
    由于指针指针使用explicit参数 必须显示声明初始化
    shared_ptr<string> pNico = new string("nico"); // ERROR
    shared_ptr<string> pNico{new string("nico")}; // OK

    也可以使用make_shared()
    shared_ptr<string> pNico = make_shared<string>("nico");
    shared_ptr<string> pJutta = make_shared<string>("jutta");

    智能指针一旦声明
    就不能再次分配 除非使用reset()
    shared_ptr<string> pNico4;
    pNico4 = new string("nico");
    //ERROR: no assignment for ordinary pointers
    pNico4.reset(new string("nico")); // OK

    shared_ptr的使用方式与实际指针使用类似 基本没什么区别

    示例 sharedPtrTest1()

    //=======================================
    对于shared_ptr中的参数 可以指定 删除器 Deleter
    示例 sharedPtrTest2()

    #include <iostream>
    #include <string>
    #include <vector>
    #include <memory>
    #include <fstream> //for ofstream
    #include <cstdio> //for remove()
    
    using namespace std;
    
    
    void sharedPtrTest1()
    {
    	shared_ptr<string> pNico(new string("nico"));
    	shared_ptr<string> pJutta(new string("jutta"));
    
    	(*pNico)[0] = 'N';
    	pJutta->replace(0, 1, "J");
    
    	vector<shared_ptr<string>> whoMadeCoffee;
    	whoMadeCoffee.push_back(pJutta);
    	whoMadeCoffee.push_back(pJutta);
    	whoMadeCoffee.push_back(pNico);
    	whoMadeCoffee.push_back(pJutta);
    	whoMadeCoffee.push_back(pNico);
    
    	for (auto ptr : whoMadeCoffee) {
    		cout << *ptr << " ";
    	}
    	cout << endl;
    	// overwrite a name again
    	*pNico = "Nicolai";
    	// print all elements again
    	for (auto ptr : whoMadeCoffee) {
    		cout << *ptr << " ";
    	}
    	cout << endl;
    	// print some internal data
    	cout << "use_count: " << whoMadeCoffee[0].use_count() << endl;
    }
    
    
    class FileDeleter
    {
    private:
    	std::string filename;
    public:
    	FileDeleter(const std::string& fn)
    		: filename(fn) {
    	}
    	void operator () (std::ofstream* fp) {
    		fp->close(); //close.file
    		std::remove(filename.c_str()); //delete file
    		cout << "delete file finish" << endl;
    	}
    };
    
    void sharedPtrTest2()
    {
    	shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"),
    		FileDeleter("tmpfile.txt"));
    }
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	sharedPtrTest1();
    	sharedPtrTest2();
    
    	return 0;
    }
    

      

     shared_ptr的误用

    下面是错误示例

    int* p = new int;

    shared_ptr<int> sp1(p);

    shared_ptr<int> sp2(p);

    这将产生错误 对于int指针有两个智能指针的内存管理器对其进行管理

    sp1 sp2 都对其关联的资源进行释放 

    正确的代码如下:

    shared_ptr<int> sp1(new int);

    shared_ptr<int> sp2(sp1);

    还有一种隐蔽的情况 也会发生这种错误:

    比如在Person 中增加一个函数setParentsAndTheirKids()

    void setParentsAndTheirKids(shared_ptr<Person> m = nullptr,
    shared_ptr<Person> f = nullptr)
    {
    mother = m;
    father = f;
    if (m != nullptr){
    m->kids.push_back(shared_ptr<Person>(this));
    }
    if (f != nullptr){
    f->kids.push_back(shared_ptr<Person>(thid));
    }
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    string name("nico");
    shared_ptr<Person> mom(new Person(name + "'s mom"));
    shared_ptr<Person> dad(new Person(name + "'s dad"));
    shared_ptr<Person> kid(new Person(name + "name"));

    kid->setParentsAndTheirKids(mom,dad);

    return 0;
    }

    但是如果在自己的类中使用包含this的shared_ptr指针 会增加引用计数

    导致无法释放

    所以引进enable_shared_from_this类

    #include <iostream>
    #include <string>
    #include <vector>
    #include <memory>
    using namespace std;
    
    
    class Person : public std::enable_shared_from_this<Person> {
    public:
    	string name;
    	shared_ptr<Person> mother;
    	shared_ptr<Person> father;
    	//vector<shared_ptr<Person>> kids;
    	vector<weak_ptr<Person>> kids;
    
    	Person(const string& n,
    		shared_ptr<Person> m = nullptr,
    		shared_ptr<Person> f = nullptr)
    		:name(n), mother(m), father(f){
    	};
    
    	~Person(){
    		cout << "delete " << name << endl;
    	}
    
    	//====================================
    	void setParentsAndTheirKids(shared_ptr<Person> m = nullptr,
    		shared_ptr<Person> f = nullptr)
    	{
    		mother = m;
    		father = f;
    		if (m != nullptr){
    			m->kids.push_back(shared_ptr<Person>(shared_from_this()));
    		}
    		if (f != nullptr){
    			f->kids.push_back(shared_ptr<Person>(shared_from_this()));
    		}
    	}
    };
    
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	string name("nico");
    	shared_ptr<Person> mom(new Person(name + "'s mom"));
    	shared_ptr<Person> dad(new Person(name + "'s dad"));
    	shared_ptr<Person> kid(new Person(name + "name"));
    
    	kid->setParentsAndTheirKids(mom,dad);
    
    	return 0;
    }
    

      

  • 相关阅读:
    Python基础知识随手记
    Java异常笔记整理
    LDAP笔记
    IntelliJ IDEA14导入项目
    字符编码
    认识显示器接口..
    4GB的内存条在32位系统中只能显示为3GB左右的原因(转)
    Velocity截取字符串.
    veloeclipse插件安装
    Velocity使用
  • 原文地址:https://www.cnblogs.com/itdef/p/4159666.html
Copyright © 2011-2022 走看看