The shared_ptr smart pointer

https://www.e-learn.cn/content/qita/725263

1 Introduction

    shared_ptr (shared memory pointer), shared_ptr is a pointer to the shared memory, multiple pointers to the same object can be shared resources, which means that multiple simultaneous shared_ptr can "own" or "share" the same object, when the last local use after automatically release the corresponding memory and resources. shared_ptr and other smart pointers are the same as defined in the <memory> header file.

2. Definitions

    // pStr here is a stack object, when after the last use will automatically clean up memory and resources

    shard_ptr<std::string>pStr(new string(“hello world”);

3. overloaded operator

  All the smart pointers and overloaded operators "." "->" "." Operator and "*", is the method where the operator is called in shared_ptr, and -> is a pointer to the object call approach, "*" is a pointer dereference it.

Example:

#include <iostream>
#include <memory>
#include <string>
#include <iostream>
using namespace std;

int main()
{     
	shared_ptr<string >p1(new string("hello "));
	p1->append("world");
	string *p2 = p1.get();
	cout << *p2;//输出为hello world
    return 0;
}

Wherein p1.get (); return shared_ptr is managed in the string *

 _Ty *get() const _NOEXCEPT
{	// return pointer to resource
return (this->_Get());
}

Note: able to access the content of which is returned when using (* p1) is one of the citations using pStr-> when members.

And we should be careful. "" - the difference between the ">"

4. Initialize shared_ptr

The constructor is explicit modified, so the following wording is wrong:

shared_ptr<string> pNico = new string("nico"); // ERROR
shared_ptr<string> pNico{new string("nico")}; // OK

   Of course, standard library also provides functions for generating a dedicated shared_ptr, and using this fast and secure way, because if the application only once using make_shared memory block, using conventional memory to apply for new action, and application memory control . When a new application using conventional memory, will not immediately control of the bare pointer to shared_ptr, if the program throws an exception at this point, the program will issue a memory leak occurs.

   Use make_shared course also the disadvantage that when used in conjunction with the weak_ptr, since only one memory is allocated, and then the memory of the object control block allocated memory it together when the case if the strong reference count is 0, reasonably At this time, say the allocation of resources should be released, but at this time if there is weak_ptr weak reference, then the resources will not be released immediately.

Example:

shared_ptr<string >p3 = std::make_shared<string>("abc");

Of course shared_ptr can also change the contents of which change hands, but can not direct new.

E.g:

:: shared_ptr std <String> pStr (new new String ( "the Hello world")); 

pStr = new new String ( "hehehe"); // error 
// correct wording should be: 
pStr.reSet (new new String ( "lalalal" )); // ok

5. use_count

    shared_ptr has called use_count () member function, call the function returns a strong reference to the use of the object (strong reference understood as a reference can use shared_ptr) number, if the number of returns 0, then prove that the object will not longer be used, it will free up memory and resources.

Of course, in addition to use_count zero outside there is another way you can free up memory that is assigned to shared_ptr nullptr.

6. Remove custom unit

When shard_ptr, will provide a default is deleted, but in some cases they need to define ourselves is deleted, then we will use the second parameter shared_ptr constructor.

Example:

shared_ptr<string> pNico(new string("nico"),
			[](string* p) 
			{
				cout << "delete " << *p << endl;
				delete p;
});

 

The default deletion can only delete the pointer, but you can not delete an array.

std :: shared_ptr <int> p (new int [10]); // not so written, but the compiler can

That is, if you want an array of new, you must define your own deleter.

E.g:

std::shared_ptr<int>pNptr(new int [10],[](int *p){delete[] p;});

Delete to remove the custom tool can also help a unique_ptr offered delete [],

E.g:

 
the shared_ptr :: STD <int> pNico (new new int [10], 
                          STD :: default_delete <int []> ()); 

the shared_ptr <int []> P (new new int [10]); // this statement will be given. 
std :: unique_ptr <int []> p (new int [10]); // OK

However, if unique_ptr statement is deleted, then it must be given the second parameter (function pointer).

E.g:

std::unique_ptr<int,void(*)(int *)>p(new int[10],[](int* p){delete[]p};

Of course, you can also define other ways to delete

Example: // delete temporary files

#include <string>
#include <fstream> // for ofstream
#include <memory> // for shared_ptr
#include <cstdio> // for remove()
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
	}
};

int main()
{
    // create and open temporary file:
    std::shared_ptr<std::ofstream> fp(new std::ofstream("tmpfile.txt"),
    FileDeleter("tmpfile.txt"));
...
}

 

   If you delete a custom mode, you must first operate in the class (); and this function's arguments must be consistent with the new parameters, but this method can be more than a constructor, which is more than one parameter can be, and remove function requires this parameter is the file name, so we need constructor passing in the file name, so you can close the file stream and the corresponding files are deleted.

Guess you like

Origin blog.csdn.net/az44yao/article/details/94186553