将对象附加到智能指针向量的最佳方法?
Best way to append object to a vector of smart pointers?
考虑以下 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;
}
class B
中的哪些方法 addX
更适合 suited/best 将新指针传递给向量的做法?考虑到 data
是非常量智能指针的向量,我知道不可能通过 const 引用传递对象或智能指针而不必 "de-const" 它们,这是不可取的并且被认为是坏的实践。但是,除非我弄错了,否则所有这些方法最终都会实例化一个 shared_ptr
然后将其复制到向量中?它们之间有什么区别?
如果你想确保你的 API 清楚地表明被调用者将取得所有权,唯一可行的方法是 add1
。从签名中可以清楚地看出,无论您提供什么,都将由被叫方保留。
您可以使用 std::move
和 .emplace_back
来改进它:
void add1(std::shared_ptr<A> _obj)
{
data.emplace_back(std::move(_obj));
}
add2
具有误导性,因为原始指针可能暗示也可能不暗示所有权。有人可以传递指向 stack-allocated 变量的指针。
add3
有同样的问题,但它更具误导性,因为非 const
引用通常用于改变对象 in-place,而不是取得它的所有权。
add2
不好,因为函数转移了所有权,不应该使用裸指针来完成。
add3
更糟,因为它是 non-idiomatic 在甚至 pre-C++11 约定中,通过传递引用来转移指针的所有权。
add1
不错。从函数声明中可以清楚地知道谁拥有资源(它是共享的)。但是,您可以避免复制共享指针:
void add1(std::shared_ptr<A> _obj) {
data.push_back(std::move(_obj));
};
考虑以下 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;
}
class B
中的哪些方法 addX
更适合 suited/best 将新指针传递给向量的做法?考虑到 data
是非常量智能指针的向量,我知道不可能通过 const 引用传递对象或智能指针而不必 "de-const" 它们,这是不可取的并且被认为是坏的实践。但是,除非我弄错了,否则所有这些方法最终都会实例化一个 shared_ptr
然后将其复制到向量中?它们之间有什么区别?
如果你想确保你的 API 清楚地表明被调用者将取得所有权,唯一可行的方法是 add1
。从签名中可以清楚地看出,无论您提供什么,都将由被叫方保留。
您可以使用 std::move
和 .emplace_back
来改进它:
void add1(std::shared_ptr<A> _obj)
{
data.emplace_back(std::move(_obj));
}
add2
具有误导性,因为原始指针可能暗示也可能不暗示所有权。有人可以传递指向 stack-allocated 变量的指针。
add3
有同样的问题,但它更具误导性,因为非 const
引用通常用于改变对象 in-place,而不是取得它的所有权。
add2
不好,因为函数转移了所有权,不应该使用裸指针来完成。
add3
更糟,因为它是 non-idiomatic 在甚至 pre-C++11 约定中,通过传递引用来转移指针的所有权。
add1
不错。从函数声明中可以清楚地知道谁拥有资源(它是共享的)。但是,您可以避免复制共享指针:
void add1(std::shared_ptr<A> _obj) {
data.push_back(std::move(_obj));
};