考虑这个小程序:
#include <memory>
#include <vector>
class Holder {
std::vector<std::unique_ptr<A> > _items;
public:
void push(A *v) {
//Perform some checks and other stuff before pushing
_items.emplace_back(v);
};
void push(std::unique_ptr<A> &v) {
push(v.release());
};
};
class A {
};
class B : public A {
};
int main()
{
Holder h;
std::unique_ptr<A> a;
std::unique_ptr<B> b;
// It works but it's too verbose
h.push(a.release());
h.push(b.release());
// It works for a because it has the right type but not for b
h.push(a);
h.push(b);
}
我想知道是否有一种简单的方法来编写h.push(b)
行而没有给自己所有权的开销。
我不想使用*b
,因为指针必须在push
方法中失去其所有权,并且我希望push
方法尽可能易于使用。 / p>
我觉得我应该从push
类中删除unique_ptr
的{{1}}重载,并使用第一个有效的示例。
有什么主意吗?
答案 0 :(得分:4)
这是正确的签名:
void push(std::unique_ptr<A> v) {
//Perform some checks and other stuff before pushing
push(std::move(v));
}
获取unique_ptr
表示您正在获取所有权。
在呼叫站点:
// It works but it's too verbose
h.push(std::move(a));
h.push(std::move(b));
这既是必需的,也是因为您希望清除所有权变更代码。
请注意,std::move(b)
代码将导致未定义的行为,因为A
缺少虚拟析构函数。
// It works for a because it has the right type but not for b
h.push(a);
此代码有毒,并且会导致错误。您只是默默地更改了unique_ptr
的所有权。 auto_ptr
具有此属性,被发现几乎不可能正确使用,已被弃用,然后从标准中删除。
不要编写使unique_ptr
像auto_ptr
一样的代码。
答案 1 :(得分:2)
您应该移动而不是通过引用传递对象:
for image_name in image_names:
for datum in data:
datum_name = datum.get("name", None)
if datum_name == image_name:
images_ids.append(datum.get("id", None))
然后:
void push(std::unique_ptr<A> v) {
push(v.release());
};
但是唯一指针上的任何h.push(std::move(a));
h.push(std::move(b));
都是难闻的气味,因此请以另一种方式实现推送:
release
并添加虚拟析构函数。
答案 2 :(得分:2)
对于export default class Posizionecliente extends Component {
constructor(props) {
super(props);
this.contiService = new ContiService();
this.state = {
conti: [],
};
}
componentDidMount() {
this.contiService.getConti().then(r => this.setState({ conti: r.data.conti }));
}
}
,您应该始终拥有所有权,在这种情况下,您不必担心释放和创建新指针。而是使用std::unique_ptr
函数。您可以将推送功能更改为此:
std::move
然后您将使用以下命令推入指针
void push (std::unique_ptr<A> v) { _items.push_back(std::move(v)); }