


C++11 new features smart pointers (shared_ptr/unique_ptr/weak_ptr)
Basic usage of shared_ptr
shared_ptr uses reference counting to manage the pointed object. When there is a new shared_ptr pointing to the same object (copying the shared_ptr, etc.), the reference count is increased by 1. When shared_ptr goes out of scope, the reference count is decremented by 1. When the reference count reaches 0, the managed memory is released.
The advantage of this is that it relieves programmers from the pressure of manually releasing memory. In the past, in order to handle exceptions in the program, it was often necessary to manually encapsulate the pointer into a class and use the destructor to release the dynamically allocated memory; now this process can be left to shared_ptr.
Generally we use make_shared to obtain shared_ptr.
cout<<"test shared_ptr base usage:"<<endl; shared_ptr<string> p1 = make_shared<string>(""); if(p1 && p1->empty()) *p1 = "hello"; auto p2 = make_shared<string>("world"); cout<<*p1<<' '<<*p2<<endl; cout<<"test shared_ptr use_count:"<<endl; cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<endl; auto p3 = p2; cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 cnt:"<<p3.use_count()<<endl; p2 = p1; cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 cnt:"<<p3.use_count()<<endl;
shared_ptr and new
shared_ptr can be initialized using a pointer returned by a new expression.
cout<<"test shared_ptr and new:"<<endl; shared_ptr<int> p4(new int(1024)); //shared_ptr<int> p5 = new int(1024); // wrong, no implicit constructor cout<<*p4<<endl;
However, the pointer returned by a new expression cannot be assigned to shared_ptr.
In addition, special attention should be paid to not mixing new and shared_ptr!
void process(shared_ptr<int> ptr) { cout<<"in process use_count:"<<ptr.use_count()<<endl; } cout<<"don't mix shared_ptr and normal pointer:"<<endl; shared_ptr<int> p5(new int(1024)); process(p5); int v5 = *p5; cout<<"v5: "<<v5<<endl; int *p6 = new int(1024); process(shared_ptr<int>(p6)); int v6 = *p6; cout<<"v6: "<<v6<<endl;
The above program fragment will output:
in process use_count:2
v5: 1024
in process use_count:1
v6: 0
It can be seen that when process p6 is used for the second time, the reference count of shared_ptr is 1, and when leaving When the scope of process is reached, the corresponding memory will be released, and p6 becomes a hanging pointer.
So, once the pointer returned by a new expression is managed by shared_ptr, do not access this memory through ordinary pointers!
shared_ptr.reset
shared_ptr can be reset to point to another object through the reset method. At this time, the reference count of the original object is reduced by one.
cout<<"test shared_ptr reset:"<<endl; cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 nt:"<<p3.use_count()<<endl; p1.reset(new string("cpp11")); cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 cnt:"<<p3.use_count()<<endl; shared_ptr deleter
You can customize a delete function to be called when shared_ptr releases the object.
void print_at_delete(int *p) { cout<<"deleting..."<<p<<'\t'<<*p<<endl; delete p; } cout<<"test shared_ptr deleter:"<<endl; int *p7 = new int(1024); shared_ptr<int> p8(p7, print_at_delete); p8 = make_shared<int>(1025);
Basic usage of unique_ptr
unique_ptr is exclusive to the object pointed to, as its name suggests. Therefore, unique_ptr cannot be copied, assigned, etc., but control can be transferred between unique_ptr through the release function.
cout<<"test unique_ptr base usage:"<<endl; unique_ptr<int> up1(new int(1024)); cout<<"up1: "<<*up1<<endl; unique_ptr<int> up2(up1.release()); cout<<"up2: "<<*up2<<endl; //unique_ptr<int> up3(up1); // wrong, unique_ptr can not copy //up2 = up1; // wrong, unique_ptr can not copy unique_ptr<int> up4(new int(1025)); up4.reset(up2.release()); cout<<"up4: "<<*up4<<endl;
unique_ptr as parameter and return value
There are two special cases for the above restrictions on copying, that is, unique_ptr can be used as the return value of the function Values and parameters are used. Although there is an implicit copy at this time, it is not unfeasible.
unique_ptr<int> clone(int p) { return unique_ptr<int>(new int(p)); } void process_unique_ptr(unique_ptr<int> up) { cout<<"process unique ptr: "<<*up<<endl; } cout<<"test unique_ptr parameter and return value:"<<endl; auto up5 = clone(1024); cout<<"up5: "<<*up5<<endl; process_unique_ptr(move(up5)); //cout<<"up5 after process: "<<*up5<<endl; // would cause segmentfault
The std::move function here will be discussed in detail later^_^
unique_ptr deleter
unique_ptr can also set deleter. Unlike shared_ptr, it needs to specify the type of deleter in the template parameter. Fortunately, we have the powerful tool decltype, otherwise it would be troublesome to write.
cout<<"test unique_ptr deleter:"<<endl; int *p9 = new int(1024); unique_ptr<int, decltype(print_at_delete) *> up6(p9, print_at_delete); unique_ptr<int> up7(new int(1025)); up6.reset(up7.release());
weak_ptr
weak_ptr is generally used in conjunction with shared_ptr. It can point to the object pointed to by shared_ptr, but it does not increase the reference count of the object. In this way, it is possible that the object pointed to by weak_ptr has actually been released. Therefore, weak_ptr has a lock function that attempts to retrieve a shared_ptr pointing to the object.
cout<<"test weak_ptr basic usage:"<<endl; auto p10 = make_shared<int>(1024); weak_ptr<int> wp1(p10); cout<<"p10 use_count: "<<p10.use_count()<<endl; //p10.reset(new int(1025)); // this will cause wp1.lock() return a false obj shared_ptr<int> p11 = wp1.lock(); if(p11) cout<<"wp1: "<<*p11<<" use count: "<<p11.use_count()<<endl;
Summary
shared_ptr uses reference counting to manage the pointed objects.
Shared_ptr can be initialized using a pointer returned by a new expression; however, a pointer returned by a new expression cannot be assigned to shared_ptr.
Once the pointer returned by a new expression is managed by shared_ptr, do not access this memory through ordinary pointers.
Shared_ptr can be reset to point to another object through the reset method. At this time, the reference count of the original object is reduced by one.
You can customize a delete function to be called when shared_ptr releases the object.
unique_ptr is exclusive to the object pointed to.
Unique_ptr cannot be copied, assigned, etc., but control can be transferred between unique_ptr through the release function.
unique_ptr can be used as the return value and parameter of the function.
unique_ptr can also set deleter, and the type of deleter needs to be specified in the template parameters.
Weak_ptr is generally used in conjunction with shared_ptr. It can point to the object pointed to by shared_ptr, but it does not increase the object's reference count.
Weak_ptr has a lock function that tries to retrieve a shared_ptr pointing to the object.
The above is the entire content of this article. I hope it will be helpful to everyone's learning. I also hope that everyone will support the PHP Chinese website.
For more articles related to the new features of C++11, smart pointers (shared_ptr/unique_ptr/weak_ptr), please pay attention to the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











C#.NET interview questions and answers include basic knowledge, core concepts, and advanced usage. 1) Basic knowledge: C# is an object-oriented language developed by Microsoft and is mainly used in the .NET framework. 2) Core concepts: Delegation and events allow dynamic binding methods, and LINQ provides powerful query functions. 3) Advanced usage: Asynchronous programming improves responsiveness, and expression trees are used for dynamic code construction.

C# is a modern, object-oriented programming language developed by Microsoft and as part of the .NET framework. 1.C# supports object-oriented programming (OOP), including encapsulation, inheritance and polymorphism. 2. Asynchronous programming in C# is implemented through async and await keywords to improve application responsiveness. 3. Use LINQ to process data collections concisely. 4. Common errors include null reference exceptions and index out-of-range exceptions. Debugging skills include using a debugger and exception handling. 5. Performance optimization includes using StringBuilder and avoiding unnecessary packing and unboxing.

Testing strategies for C#.NET applications include unit testing, integration testing, and end-to-end testing. 1. Unit testing ensures that the minimum unit of the code works independently, using the MSTest, NUnit or xUnit framework. 2. Integrated tests verify the functions of multiple units combined, commonly used simulated data and external services. 3. End-to-end testing simulates the user's complete operation process, and Selenium is usually used for automated testing.

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#.NET is still important because it provides powerful tools and libraries that support multiple application development. 1) C# combines .NET framework to make development efficient and convenient. 2) C#'s type safety and garbage collection mechanism enhance its advantages. 3) .NET provides a cross-platform running environment and rich APIs, improving development flexibility.

Interview with C# senior developer requires mastering core knowledge such as asynchronous programming, LINQ, and internal working principles of .NET frameworks. 1. Asynchronous programming simplifies operations through async and await to improve application responsiveness. 2.LINQ operates data in SQL style and pay attention to performance. 3. The CLR of the NET framework manages memory, and garbage collection needs to be used with caution.

C#.NETissuitableforenterprise-levelapplicationswithintheMicrosoftecosystemduetoitsstrongtyping,richlibraries,androbustperformance.However,itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical,wherelanguageslikeRustorGomightbepreferable.

C#.NET is a popular choice for building microservices because of its strong ecosystem and rich support. 1) Create RESTfulAPI using ASP.NETCore to process order creation and query. 2) Use gRPC to achieve efficient communication between microservices, define and implement order services. 3) Simplify deployment and management through Docker containerized microservices.
