Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shared_ptr and references in C++

References in C++ are a conveneint construct that allow us to simplify the following C code:

f(object *p){
  //do something
}

int main(){
  object* p = (object*) calloc(sizeof(object));
  f(p);
}

to

f(object& o){
  //do something
}

int main(){
  object o = object();
  f(o);
}

Shared pointers are another convenience in C++ that simplify memory management. However, I am not sure how to pass a shared_ptr to a function like f(object& o) which accepts arguments by reference?

f(object& o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(*p);
}

Will the shared pointer be incremented when its object is passed by reference to a function?

like image 705
D R Avatar asked Sep 09 '09 22:09

D R


1 Answers

Take a shared_ptr by value, and the reference count will increase. This is easier when you typedef it:

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr obj)
{
    obj->/* stuff*/;
    obj.reset(); //only resets this local copy, that means:
                 // reduce reference count (back to 1), and
                 // set obj to point at null.
}

int main(void)
{
    object_ptr obj(new object());
    foo(obj);
}

Keep in mind references are aliases. When you pass by reference, you're not passing pointers, copies, etc..., you're aliasing another object. (In reality they are implemented as pointers):

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr& obj)
{
    obj.reset(); // the references was never increased, since a copy has not
                 // been made, this *is* obj in main. so the reference 
                 // goes to 0, and obj is deleted
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj); // after this, obj has been reset!
}

Always remember to be const correct, to prevent errors:

typedef boost:shared_ptr<object> object_ptr;

void foo(const object_ptr& obj)
{
    obj.reset(); // cannot do! 
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj);
}

I think you should prefer to pass smart pointers as references when possible, to avoid extraneous increments and decrements (and copies and whatnot).

like image 182
GManNickG Avatar answered Sep 24 '22 23:09

GManNickG