Search code examples
c++shared-ptr

How to assign a reference to a shared pointer to another shared pointer


I am refactoring some code which uses raw pointers to use shared pointers instead. In the original code, there is a raw pointer to a list object, let's call it EntityList I have typedefed a shared pointer to an EntityList in the EntityList.h file, as follows:

using EntityList_ptr = std::shared_ptr<EntityList>;

In the code to refactor, there is one place where the list can be set to one of several types of list.

Here is where the lists are created:

EntityList_ptr typeZeroList = EntityList_ptr (new ZeroList);
EntityList_ptr typeOneList = EntityList_ptr (new OneList);
EntityList_ptr typeTwoList = EntityList_ptr (new TwoList);
EntityList_ptr typeThreeList = EntityList_ptr (new ThreeList);

And here is where I set the list to the appropriate type:

setList (int type) {
    EntityList** list;

if (type == 0) {
    list = &typeZeroList;
} else if (type ==1) {
    list = &typeOneList;
} else if (type ==2) {
    list = &typeTwoList;
} else {
    list = &typeThreeList;
}

I cannot figure out how to refactor this. Here is my stab at it (I tried three different approaches in the if-else part below.:

setList (int type) {
    std::shared_ptr<EntityList_ptr> list;

    if (type == 0) {
        list = &typeZeroList;
    } else if (type ==1) {
        list = typeOneList.get();
    } else if (type ==2) {
        list = &(typeTwoList.get());
    } else {
        list = std::shared_ptr<Entity> (typeThreeList.get());
    }

None of the above approaches work. I've tried various others too, but they all amount to stabbing in the dark without knowing what I am doing. Any ideas as to what I should do and explanations why would be welcome.


Solution

  • Just as you replaced EntityList* with EntityList_ptr elsewhere in your code, you can do the exact same thing here. EntityList** would simply become EntityList_ptr*, eg:

    setList (int type) {
        EntityList_ptr* list;
    
        if (type == 0) {
            list = &typeZeroList;
        } else if (type ==1) {
            list = &typeOneList;
        } else if (type ==2) {
            list = &typeTwoList;
        } else {
            list = &typeThreeList;
        }
    
        // use *list as needed...
    }
    

    Taking the address of a variable of type T with the & operator produces a pointer of type T* 1. In this case, T is EntityList_ptr.

    1: provided T does not override operator&, which std::shared_ptr does not.

    So, since typeXXXList are EntityList_ptr variables, taking their addresses with the & operator produce EntityList_ptr* pointers.