Introduce to Smart Pointer

In computer science, a smart pointer is an abstract data type that simulate a pointer while providing additonal features. -- [WikiPedia](http://en.wikipedia.org/wiki/Smart_pointer)

In the C++ language, smart pointer implements as a template class and override the behaviour of raw pointer, such as dereferencing and assignment. What's more, smart poiner also providing addtional memory managment algorithms.

From the information above, we learn that:

  1. Smart pointer is a decorator of raw pointer. So smart pointer has more functions/methods than raw pointer, and use more convenient than raw pointer.
  2. Smart poiner is as well a template class, so it has the same usage of template class. For example: shared_ptr<int> int_ptr.

Two kind of smart pointers

  1. With shared pointer there could be multiple instance of the smart pointer pointing to the same object. It use some form of reference counting to manage the lifetime of the object they point to.
  2. With unique pointer, it has the restriction of only one instance of the smart pointer managing the object.

Difference between STL and Boost

Here are some saying from wiki and stackoverflow:

  • std::shared_ptr is the C++0x form of tr1::shared_ptr, and boost's boost::shared_ptr should behave the same. -- wikiepedia
  • According to the Wikipedia C++0x page: The TR1 implementation lacked certain pointer features such as aliasing and pointer arithmetic, but the C++0x version will add these. -- wikiepedia
  • Now, C++11 provides?std::unique_ptr, as well as improvements to?std::shared_ptr?and?std::weak_ptr?from TR1.?std::auto_ptr?is deprecated. -- stackoverflow

In general, there is little difference between std and boost on smart pointer operations.

Performance on smart pointers

Define a class with a double variable, and just do one thing: variable num multiply itself 10,000 times.

class MyClass
{
public:
    MyClass(double input);
    ~MyClass();
private:
    double num;
};

MyClass::MyClass(double input){
    num = input;
    for (int i=0;i<10000;++i){
        num = num * num;
    }
}

The main function of raw pointer:

int main (int argc, char *argv[]){
    int input = 1000;

    if (argc > 1){
        input = atoi(argv[1]);
    }

    for (int i=0;i<input;++i){
        MyClass *obj = new MyClass(2.0);
    }

    return 1;
}

The main function of smart pointer:

int main (int argc, char *argv[]){
    int input = 1000;

    if (argc > 1){
        input = atoi(argv[1]);
    }

    for (int i=0;i<input;++i){
        shared_ptr<MyClass> obj(new MyClass(2.0));
    }

    return 1;
}

Then let input to be 10,000:

Let input to be 50,000

Let input to be 100,000

Here is the graph of performance:

Conclusion

From the experienments has done, we come to the conclusion that smart pointer's performance is closed to raw pointer when using in the normal way.

Additional experiments

In order to get more details of smart pointer's performace, here is another experiment, just allocation but not calculate:

A new class:

Class MyClass{
public:
    MyClass(double input);
    ~MyClass();
    void print();
private:
    double num;
};
MyClass::MyClass(double input){
    num = 2;
    for (int i=0;i<input;i++){
        num = num * num;
    }
}
MyClass::~MyClass(){ }
void MyClass::print(){
    cout << num << " ";
}

The main function of smart pointer:

int main(int argc, char *argv[]){
    int input = 1;
    if (argc > 1){
        input = atoi(argv[1]);
    }

    shared_ptr<MyClass> obj(new MyClass(input));

    return 1;
 }

The main function of raw pointer:

int main(int argc, char *argv[]){
    int input = 1;

    if (argc > 1){
        input = atoi(argv[1]);
    }

    MyClass* obj = new MyClass(input);
    delete obj;

    return 1;
}

And the result:

Conclusion: Compared to raw pointer, smart pointer spends more time on allocating.

Usages

First of all, #include <memory>

  • One of constructors:
template<class Y>
explicit shared_ptr(Y* ptr);

The key word explicit avoids compiler to construct object using implicit conversion. For example:

shared_ptr<MyClass> obj = new MyClass();

In the case without using explicit key word: obj will convert to shared_ptr type.

  • create a smart pointer:
shared_ptr<MyClass> obj(new MyClass(2.0));
  • create a vector of smart pointer:
vector<shared_ptr<CDNA> > data;

Please notice we use "> >", not ">>". ">>" refers to stream operator.

  • delete a smart pointer:
obj.reset();
  • Invoking a method looks like raw pointer.
obj->print();
  • To get the raw pointer:
obj.get(index);
  • To swap two smart pointers:
swap(obj1, obj2);