Smart Pointer in C++

smart pointer has been introduce to c++ for years. Actually when I took c++ class, the professor barely talk about it. We still discussed about the how to use new and delete keyword to create and destroy pointer. Well, while I worked for internship, large codebase I worked with still not compatible with c++11 standard.

LOL. OK. OK. I admit it. The true is I am too lazy to learn and practice modern c++ new features.


Smart Pointer

As all we know that, pointer is powerful and efficient. You can use pointer to access the memory directly, but it also is dangerous. If you have manually handle memory management, it will become to your nightmare.
Consider the following C++ case

1
2
Foo *foo_ptr = new Foo();
foo_ptr->doSomething();

We have to delete foo_ptr when it finish its job. However, most of time foo_ptr will stay forever inside your memory because you forget to delete it. Even worst, sometimes we try to access pointer but we already delete it at somewhere you don’t remember. Therefore, smart pointer is created to solve this problem.

The truth of smart point is a container to store raw pointer. raw pointer is create by new keyword that lack of destructor, which makes developer have to manually deallocate the memory. a container class to store the raw pointer will construct and destroy inside the life of scope. This container will treat like a local variable, and its destructor will cleanup raw pointer.
In the meanwhile, we still can get benefits of pointer, because smart pointer will function as same as an raw pointer.

Simple Smart Pointer Example

To use smart pointer is simple. let’s see the following example.

class Detector {
    int             face_num;
    DETECT_FEATURE     m_feature;    
public:
    DETECTOR_ERROR     updateFrame(cv::Mat frame);
    DETECT_FEATURE     getFeature();
    int                getNumberFace() const;
}

This is a simple detector class implementation. In the old world, we maybe have to use it in this way.

// call Detector and use it
{
    Detector* m_detect = new Detector();
    m_detect->updateFrame(frame);
    int num_face = m_detect->getNumberFace();

    //Delete it if you are done with it. 
    //delete m_detect;
}

See the delete maybe not happy with you. You cannot delete it at the middle of code. You probably cleanup at the end of code, which about hundreds lines later.

Then what about smart pointer? let’s look at that.

// use smart pointer 
#include <memory> //header file, std namespace. 
{
    // init unique_ptr
    std::unique_ptr<Detector> m_detect_ptr(new Detector);

    // you are free to use it like a raw pointer
    // nothing different

    m_detect_ptr->updateFrame(frame);
    int num_face = m_detect_ptr->getNumberFace();


    // Netflix and Chill    
}

Yes, That’s it.

Types of smart pointers

I am not very familiar with all of these smart pointers honestly. At least, I never use weak_ptr. There is three basic smart pointer types.

  • unique_ptr
  • shared_ptr
  • weak_ptr
  • auto_ptr

unique_ptr

unique_ptr is used exactly as as pinter. it cannot be copied or shared. auto_ptr is similar to unique_ptr. Check the example above.

shared_ptr

shared_ptr use when you want to assign one raw pointer to multiple objects. The idea is when you assign the raw pointer to another object or smart pointer, there is counter to keep tracking this sharing. Raw pointer is deleted Only when all containers that contain the raw pointer are deleted. Therefore, shared_ptr has 2*sizeof(pointer)