C++: 10. Smart pointers

Smart pointer function:

General pointers have the problem of resource leakage. The smart pointer will definitely ensure that resources are automatically released (delete will be called automatically), without user participation.

Why is delete automatically called?

In fact, the smart pointer is also defined by the class, and the destructor will be automatically called when the function is exited by using the pointer on the stack.

So the pointer on the heap cannot be used, because the exit function will not be destructed. Don't define a global one, because it will be released when the program ends.

Header files: #include <memory>


1. Smart pointers with reference counting.

1) The shared_ptr   strong smart pointer can change the reference count of the resource. There will be a circular reference problem.

If multiple shared_ptr points to the same resource. The reference count of the resource is incremented by 1 each time. If it is not pointed to, subtract 1. When the reference count reaches 0, the resource is automatically released.

The internal reference counting of shared_ptr is thread-safe, but the reading of the object needs to be locked.

Initialization method: A smart pointer is a class, not a pointer (although its member variable is a pointer). So you cannot assign a pointer directly to a smart pointer. That is to say: shared_ptr<int> pra = new int; This way of writing is wrong. Instead shared_ptr<int> pra(new int);

2) The weak_ptr       weak smart pointer will not change the reference count of the resource.

Weak smart pointers cannot directly access objects, but if they are promoted to strong smart pointers (reference count + 1), they can be accessed, using the lock() method. The premise resource still exists and the reference count is not 0. If the resource is gone, of course it points to NULL. Out of local destructor -1;

Multi-threading is also safe, and there will be no other threads destructed just after the promotion. Because of +1, +1 is locked.

Weak smart pointers can accept strong smart pointers directly.

Mentally retarded needles cannot use -> to access objects. It is necessary to upgrade the mentally handicapped needle to a strong pointer. shared_ptr<A> ptra = _ptra.lock(); // promotion

Suggestions for using shared_ptr and weak_ptr:

Conclusion: Use strong smart pointers where objects are created, and use weak smart pointers everywhere else.

2. Smart pointers without reference counting.

1、auto_ptr

The C++ standard provides auto_ptr. This smart pointer does not support a copy constructor. When thinking about ptr2(ptr1); it will set ptr1 to NULL, and ptr2 points to the address before ptr1. Therefore, the use of auto_ptr provided by the C++ standard is prohibited .

Ownership of resources can be transferred arbitrarily, but users cannot perceive it.

2、scope_ptr

 Copy construction and assignment are prohibited. way is private. Ownership cannot be transferred arbitrarily.

3、unique_ptr

Only one unique_ptr can point to a given object at a time. Can not be assigned, can not be copied. But the user can call the function (move) and also transfer the ownership.

Remaining issues: 1. Copy construction and assignment cannot be used in the same scope, but they can be called when a function returns.
                             2. Not all resources use delete, so how to define the deleter.

unique_ptr<int> getUniquePtr_1()
{
	unique_ptr<int> p(new int);
	return p;   返回局部变量,C++优化规则.
}
unique_ptr<int> getUniquePtr_2()
{
    return unique_ptr<int> (new int);返回临时量
}

int main()
{

	unique_ptr<int> p1(new int);
	unique_ptr<int> p2(p1);   拷贝构造报错
	p2 = p1;                  赋值重载报错

	unique_ptr<int> p3 = getUniquePtr_1();正确,直接拷贝构造p3.
}

在unique_ptr中拷贝构造与赋值重载是放在public中的,通过在后面加=delete。从而达到删除该函数的目的,导致无法使用。
但其实还提供了右值引用(C++11)的拷贝构造与赋值重载。在这里调用的就是右值引用的函数。

Circular reference (cross reference) problem of smart pointer:

Solution: Use strong smart pointers where objects are created, and use weak smart pointers everywhere else. That is to say, the pointers in the class can use weak pointers.

Reason: Weak pointer reference count will not increase by one.


An example of promoting a weak pointer to a strong pointer:

class B;
class A
{
public:
	A(){ cout << "A()" << endl; }
	~A(){ cout << "~A()" << endl; }
	void func(){ cout << "call A::func" << endl; }
	weak_ptr<B> _ptrb;
};
class B
{
public:
	B(){ cout << "B()" << endl; }
	~B(){ cout << "~B()" << endl; }
	void test()
	{
		// 想通过_ptra访问A对象的func方法,调用一下
		shared_ptr<A> ptra = _ptra.lock();  // 提升
		if (ptra != NULL) // 提升成功,调用func方法
		{
			ptra->func();
		}
	}
	weak_ptr<A> _ptra; // operator-> 不允许通过weak_ptr访问对象
};

int main()
{
	shared_ptr<A> ptra(new A());
	shared_ptr<B> ptrb(new B());
	ptra->_ptrb = ptrb;
	ptrb->_ptra = ptra;

	ptrb->test();
}

Guess you like

Origin blog.csdn.net/qq_41214278/article/details/83899135