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.