C++ implements smart pointers (1)

Reference from "C5-C++ Primer" and related experiments in the laboratory building.

1. The concept of smart pointers

  • The introduction of smart pointers:

In C++, dynamic memory management is performed through the new/delete operator. Dynamic memory usage is prone to problems because it is difficult to ensure that memory is freed at the right time. Sometimes you forget to free the memory, resulting in memory leaks; sometimes you release the pointer when it still refers to the memory, resulting in a pointer that refers to illegal memory. Therefore, in order to use dynamic memory more easily and safely, C++11 provides the smart pointer type to manage dynamic objects.

  • Use of smart pointers:
The so-called smart pointer, first of all, it is a pointer, so it can point to memory resources; then it is different from ordinary pointers, it is intelligent, and the so-called intelligence refers to it: 1. It can automatically release memory for you, 2. It is also possible to know when it is safe to free memory.

The standard provides two types of smart pointers: shared_ptr allows multiple pointers to point to the same object; unique_ptr exclusively refers to the object; weak_ptr points to the object managed by shared_ptr. This experiment mainly realizes the function of shared_ptr.

  • The realization principle of smart pointer:
The implementation of smart pointers in C++ mainly relies on two technical concepts:
1. Destructor, a function that is called when the object is destroyed, for stack-based objects, if the object leaves its scope, the object will be automatically Destruction, and the destructor will be called automatically at this time.

2. Reference counting technology, maintains a counter to track the number of references of resources (such as memory). When the resource is referenced, the counter value is incremented by 1, and when the resource is dereferenced, the counter value is decremented by 1.

The general implementation principle of smart pointers is to check the reference count of the referenced object in the destructor, and if the reference count is 0, the memory of the object is actually released.

2. Implementation version v1

  • Define a smart pointer class
  • Create constructor: have default constructor; specify type constructor
  • Defined as a template class
  • Destructor: free memory
Implement smart pointers: header file smartpointer.h
/*
* file name : smartpointer.h
* desp : smart pointer version v1
*/
#ifndef __SMARTPOINTER_H__
#define __SMARTPOINTER_H__

template <typename T> // Define the smart pointer class as a template class
class SmartPointer {
public:
    // default constructor
    SmartPointer():mPointer(NULL) {std::cout <<"create unknown smart pointer."<< std::endl;}    
    // Constructor that accepts different pointer types
    SmartPointer(T *p):mPointer(p) {std::cout <<"create smart pointer at "<<static_cast<const void*>(p)<<std::endl;}     
    // destructor
    ~SmartPointer(){
        std::cout << "release smart pointer at "<<static_cast<const void*>(mPointer)<<std::endl;
        // Implement the automatic destruction mechanism of memory resources
        if (mPointer) delete mPointer;
    }
private:
    T *mPointer; // Point to the actual memory resource corresponding to the smart pointer, define the internal resource pointer type according to the automatic parameter deduction rules
};
#endif // __SMARTPOINTER_H__

Test smart pointer: test file sptestcase1.cpp

/*
* file name : sptestcase1.cpp
* desp : smart pointer test code case1 to test the creation and destruction of smart pointers
*/

#include <iostream>
#include "smartpointer.h"
class SomeClass{
public:
    SomeClass(){std::cout << "SomeClass default constructor !"<<std::endl;}
};

void testcase1()
{
    // Create an unknown smart pointer
    SmartPointer<char> spunknown;
    // create a null smart pointer
    SmartPointer<char> spnull = NULL;
    // Create a smart pointer to the concrete class
    SmartPointer<SomeClass> spclass = new SomeClass;
    // create a smart pointer to the string
    SmartPointer<const char> spstr = "Hello world!";  
}

int main(void)
{
    testcase1();
    return 0;
}

Compile and execute:

$ g++ -o sptestcase1 sptestcase1.cpp
$ ./sptestcase1

Analysis of running results:


  • Insufficient V1 version

Simple implementation of the smart pointer class, there is an error when the smart pointer frees the pointer to "hello world". Our smart pointers cannot point to memory resources that cannot be freed by delete.

3. Checking and filling gaps in knowledge points

  • Different uses of new
(1) int *p=new int;//No initialization
(2) int *p=new int(5);//initialize to 5
(3) Create class Test *test=new Test(); delete test;//Add parentheses to call the constructor without parameters, and call the default constructor or the only constructor without parentheses
(4) int *p=new int[10];//Open up an array with a capacity of 10 delete []p;
  • class template
//class definition
template<class T>
class Test
{
private:
    T n;
    const T i;
public:
    Test():i(0) {}
    Test(T k);
    ~Test(){}

    void print();
    T operator+(T x);
};
// use of the class
Class name <actual type> eg.Test<int> test;//Declare an object
  • staic_cast<const void *>(p)

//address? conversion type? 

What we define here is a template class, because we don't know the specific type of this pointer. const void * is used.

 const void * p This defines a pointer p, p can point to any type of value, but the value it points to must be a constant. In this case, we cannot modify the pointed object, but we can make the pointer point to other objects.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325680536&siteId=291194637