简体   繁体   中英

Best way to append object to a vector of smart pointers?

Considering the following classes:

class A {
 public:
    A() {};
 protected:
    int m1;
    float m2;
    // ...
}

class B {
 public:
    B() { };
    void add1(std::shared_ptr<A> _obj) { 
        data.push_back(_obj); 
    };
    void add2(A* _obj) { 
        data.push_back(_obj); 
    };
    void add3(A& _obj) { 
        data.push_back(&_obj); 
    };
 private:
    std::vector<std::shared_ptr<A>> data;
}

which of the methods addX in class B would be more suited/best practice for passing a new pointer into the vector? Considering that data is a vector of non-const smart pointers, I understand it is not possible to pass the object or the smart pointer by const reference without having to "de-const" them which is not advisable and considered bad practice. However, unless I am mistaken, all those methods end up instantiating a shared_ptr and then copying it into the vector? What are the differences between them?

If you want to ensure that your API makes it clear that the callee is going to take ownership, the only viable method is add1 . It makes it clear from the signature that whatever you give it is going to be retained by the callee.

You can improve it by using std::move and .emplace_back :

void add1(std::shared_ptr<A> _obj) 
{ 
    data.emplace_back(std::move(_obj)); 
}

add2 is misleading, as a raw pointer might or might not imply ownership. Someone could pass a pointer to a stack-allocated variable.

add3 has the same problem, but it is even more misleading as non- const references are commonly used for mutating an object in-place, not taking ownership of it.

add2 is bad, because the function transfers ownership, and that shouldn't be done using bare pointers.

add3 is even worse, because it is non-idiomatic in even pre-C++11 conventions, to transfer ownership of a pointer by passing a reference.

add1 is good. It is clear from the function declaration who owns the resource (it is shared). However, you can avoid copying of the shared pointer:

void add1(std::shared_ptr<A> _obj) { 
    data.push_back(std::move(_obj)); 
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM