Refer to the Reference

There’s nothing to talk about

int i = 0;
int& j = i;
Copy the code

J is equivalent to a copy of I, passing function arguments by reference. Instead of producing a copy of the argument in memory, it operates directly on the argument. Therefore, it is more efficient to pass parameters by reference than by ordinary variables when they are passing large amounts of data.

A reference is no different from a raw object call

Pointer to the Pointer

1. Primitive Pointers

There’s nothing to talk about. omit

C++ supports the use of the and operator new to dynamically allocate and delete free objects. Forgetting delete can cause a memory leak. So they invented the smart pointer, which is not very smart.

2. Smart Pointers

Smart Pointers need to import headers, and reference counting algorithms are used in C++11 to manage memory automatically. A smart pointer is a wrapper around the original pointer, a special object.

Smart Pointers commonly used in modern C++ can be divided into three types:

  • unique_ptr
  • shared_ptr
  • weak_ptr
shared_ptr

Shared_ptr is a standard pointer. After a shared_Ptr is initialized, it can be passed to other shared_PTR smart Pointers. All Pointers point to the same memory address.

Initialization mode:

auto ptr = std::make_shared<int>(10); Shared_ptr <int> ptr1 = make_shared<int>(10); Shared_ptr <People> ptr3(new People(121341,"hahha"));Copy the code

Copy pointer:

struct People { int id; string name; People(const int& id_,const string& name_) : id{id_} , name{name_}{ } }; Auto ptr3 = make_shared<People>(123,"xlu"); cout<< ptr3 <<endl; Copy pointer: Auto ptr4(ptr3); cout<< ptr4 <<endl; 0x13405651570 0x13405651570 Two Pointers point to the same addressCopy the code

Swap Pointers:

Shared_ptr <People> ptr5(nullptr); ptr5.swap(ptr3); cout<< ptr3 <<endl; cout<< ptr5 <<endl; Output: 0 0x1CCBEF31570Copy the code
unique_ptr
  • The unique_ptr pointer is not shared, cannot be copied, can only be moved.
  • Unique_ptr It prevents other smart Pointers from sharing the same object, thus ensuring code security

Cpp11 does not have a unique; it was added to CPP14

Create:

unique_ptr<People> ptr6 = make_unique<People>(134,"hahah"); cout<< ptr6->id << ":" << ptr6->name <<endl; <! --> auto ptr7 = STD ::move(ptr6); cout<< ptr7->id << ":" << ptr7->name <<endl;Copy the code
weak_ptr

There are still memory leaks in shared_ptr, such as two classes with Pointers to each other’s members:

struct A; struct B; struct A { std::shared_ptr<B> pointer; ~A() {STD ::cout << "A is destroyed "<< STD ::endl; }}; struct B { std::shared_ptr<A> pointer; ~B() {STD ::cout << "B destroyed "<< STD ::endl; }}; int main() { auto a = std::make_shared<A>(); auto b = std::make_shared<B>(); a->pointer = b; b->pointer = a; }Copy the code

Let’s look at the reference counts for a and b:

cout << a.use_count() << endl; cout << b.use_count() << endl; Output: 2 2Copy the code

The destructor was also not executed, but the program completed, indicating a memory leak. The pointer inside a and B references a and B at the same time, which makes the reference count of both a and B become 2. When leaving the scope, the reference count of this region can only be reduced by 1. There is no way for outsiders to find this region, causing a memory leak

Weak_ptr is our main character weak_ptr:

Weak_ptr is a weak reference that does not increase the reference count and cannot use * and -> operators. Its main purpose is to check whether shared_ptr exists. Expired () returns false if the resource is not released. Otherwise return true.

Weak_ptr can point to shared_ptr, we modify the above example:

#include <iostream> #include <memory> using namespace std; struct A; struct B; struct A { weak_ptr<B> pointer; ~A() {cout << "A destroyed "<< STD ::endl; }}; struct B { weak_ptr<A> pointer; ~B() {cout << "B destroyed "<< STD ::endl; }}; int main() { auto a = make_shared<A>(); auto b = make_shared<B>(); a->pointer = b; b->pointer = a; cout << a.use_count() << endl; cout << b.use_count() << endl; cout << a->pointer.expired() << endl; cout << b->pointer.expired() << endl; return 0; }Copy the code

The output is as follows:

1 1 0 0 B destroyed A destroyedCopy the code