c++ - 调用接受 unique_ptr 对象的函数
问题描述
我有一个函数,其中回调接收一个event
持有 unique_ptr 实例的data
. char*
我可以通过它来检索event.data.get()
应该给我指针而不是所有权,从而允许对象自由删除它。现在我有另一个函数,它接受一个 unique_ptr 实例,otherdata
当然管理所有权,所以该函数可以自由地释放它。所以我试图data
从回调中获取并将其传递给安全的函数otherdata
。
void cbdata(const DataEvent& event){
char* datatobewritten = event.data.get();
stream.write(std::move(datatobewritten),event.length));
}
上面的示例似乎确实有效,但我不确定这是否是正确的方法。事件是否放弃所有权?如果是这样,放弃所有权是否安全?
为什么这会导致编译器错误:Call to implicitly-deleted copy constructor of 'std::unique_ptr<char []>'
?
void cbdata(const DataEvent& event){
stream.write(event.data,event.length);
}
如果 event.data 给我一个 unique_ptr 并且 stream.write 需要一个 unique_ptr 那么上面的代码不应该正常工作吗?或这个
stream.write(std::move(event.data), event.length);
抱歉,我的 C++ 知识非常有限,所以 unique_ptr 和 move 语义非常混乱。
解决方案
stream.write
您想要拥有正在打印的事件片段的所有权,这有点不寻常。似乎它拥有事件的一部分,而调用者仍然是其余部分的所有者。在那次调用之后,一个event
对象仍然是不完整的,因为它event.data
被放弃了。
此外,您cbdata
通过const&
. 这是一种“借用且不改变”的语义。因此,它不应授予其所有权event
或其任何部分。
一些选项:
将整个事件的所有权传递给了
stream
,而不仅仅是data
。不过,您cbdata
需要先获得所有权。不要给
stream
. 通常流仅用于向用户呈现数据,而不是以任何方式操纵它们。更改您的活动,以便它可以
data
永久发布。你需要这样的东西:std::unique_ptr<DataType> Event::releaseData() { return std::move(this->data); //after the call, this->data is 'nullptr'! }
当然,在其余的课程中,必须支持 nullptr
Event
的情况。data
请注意,这会更改
event
对象,而不是const
函数。您cbdata
将不适用于const&
事件对象。您还可以将数据复制到流中。如果数据很大,可能效率低下,但如果
DataType
是可复制的,则完全可以。你可以这样做:void cbdata(const DataEvent& event){ stream.write(std::make_unique<DataType>(*event.data),event.length); }
与任何其他副本一样,您必须注意,当副本被销毁时,实际上只删除了复制的数据。不应删除原件和副本之间共享的任何内容。
推荐阅读
- ios - 如何设置自定义collectionView Cell Frame?
- google-apps-script - getData 方法返回的最大记录数是多少
- php - 寻找命名空间“安全”,没有找到
- android - 构建风味时如何更改android中的导航抽屉菜单?
- c++ - 从模板化父类中的派生内部类访问受保护的成员变量
- python - Flask 中接收到的图像的形状
- tortoisegit - 如果我必须回滚更改,是否需要在 Git 中创建新分支?
- c# - C# winform 发送请求内容类型 application/x-www-form-urlencoded with Restsharp
- html - 网格项目不会留下一个网格单元格
- ruby - 需要 rspec 中包含 ruby 文件的整个文件夹