- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想将 unique_ptr 移动到其对象的方法:
class Foo {
void method(std::unique_ptr<Foo>&& self) {
// this method now owns self
}
}
auto foo_p = std::make_unique<Foo>();
foo_p->method(std::move(foo_p));
auto raw_foo_p = foo_p.get();
raw_foo_p->method(std::move(foo_p))
Server::accept
先然后
Session::start
.
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
using namespace boost::system;
using namespace boost::asio;
using boost::asio::ip::tcp;
class Session /*: public std::enable_shared_from_this<Session>*/ {
public:
Session(tcp::socket socket);
void start(std::unique_ptr<Session>&& self);
private:
tcp::socket socket_;
std::string data_;
};
Session::Session(tcp::socket socket) : socket_(std::move(socket))
{}
void Session::start(std::unique_ptr<Session>&& self)
{
// original code, replaced with unique_ptr
// auto self = shared_from_this();
socket_.async_read_some(buffer(data_), [this/*, self*/, self(std::move(self))] (error_code errorCode, size_t) mutable {
if (!errorCode) {
std::cout << "received: " << data_ << std::endl;
start(std::move(self));
}
// if error code, this object gets automatically deleted as `self` enters end of the block
});
}
class Server {
public:
Server(io_context& context);
private:
tcp::acceptor acceptor_;
void accept();
};
Server::Server(io_context& context) : acceptor_(context, tcp::endpoint(tcp::v4(), 8888))
{
accept();
}
void Server::accept()
{
acceptor_.async_accept([this](error_code errorCode, tcp::socket socket) {
if (!errorCode) {
// original code, replaced with unique_ptr
// std::make_shared<Session>(std::move(socket))->start();
auto session_ptr = std::make_unique<Session>(std::move(socket));
session_ptr->start(std::move(session_ptr));
}
accept();
});
}
int main()
{
boost::asio::io_context context;
Server server(context);
context.run();
return 0;
}
g++ main.cpp -std=c++17 -lpthread -lboost_system
最佳答案
对于您的第一个代码块:std::unique_ptr<Foo>&& self
是一个引用并为其分配一个参数 std::move(foo_p)
,其中 foo_p
是一个名为 std::unique_ptr<Foo>
只会绑定(bind)引用 self
至 foo_p
, 意思是 self
将引用foo_p
在调用范围内。
它不会创建任何新的 std::unique_ptr<Foo>
托管的所有权Foo
对象可以转让。没有移动构造或分配发生,Foo
对象仍然随着 foo_p
的破坏而被破坏在调用范围内。
因此,此函数调用本身不存在未定义行为的风险,尽管您可以使用引用 self
以可能导致 body 出现未定义行为的方式。
也许你打算拥有 self
成为 std::unique_ptr<Foo>
而不是 std::unique_ptr<Foo>&&
.在那种情况下 self
将不是引用,而是托管 Foo
的所有权的实际对象。如果使用 std::move(p_foo)
调用,将通过移动结构传输并且在 foo_p->method(std::move(foo_p))
中的函数调用后会被销毁连同托管Foo
.
此替代变体本身是否具有潜在的未定义行为取决于使用的 C++ 标准版本。
在 C++17 之前,允许编译器在评估 foo_p->method
之前选择评估调用的参数(以及参数的相关移动构造)。 .这意味着,foo_p
可能已经从 foo_p->method
开始被评估,导致未定义的行为。这可以按照您建议的方式进行修复。
由于 C++17 保证后缀表达式(这里是 foo_p->method
)在调用的任何参数之前被评估,因此调用本身不会有问题。 (但 body 可能会导致其他问题。)
后一种情况的详细信息:foo_p->method
被解释为 (foo_p->operator->())->method
, 因为 std::unique_ptr
提供此 operator->()
. (foo_p->operator->())
将解析为指向 Foo
的指针由 std::unique_ptr
管理的对象.最后 ->method
解析为成员函数 method
那个对象。在 C++17 中,此评估发生在对 method
的参数进行任何评估之前。因此是有效的,因为没有来自 foo_p
的移动已经发生了。
然后参数的评估顺序是设计未指定的。所以很可能 A) unique_ptr foo_p
可以从之前搬走 this
作为参数将被初始化。和 B) 它将 被时间感动method
运行并使用初始化的 this
.
但是 A) 不是问题,因为第 8.2.2:4 节,正如预期的那样:
If the function is a non-static member function, the this parameter of the function shall be initialized with a pointer to the object of the call,
the C++11 specification guarantees that transferring ownership of an object from one unique_ptr to another unique_ptr does not change the location of the object itself
self(std::move(self))
创建类型为
std::unique_ptr<Session>
的 lambda 捕获(不是引用)用引用
self
初始化, 指的是
session_ptr
在
accept
中的 lambda 中.通过
Session
的移动 build 所有权对象从
session_ptr
转移给 lambda 的成员。
async_read_some
, 这将(因为 lambda 不是作为非常量左值引用传递)将 lambda 移动到内部存储中,以便以后可以异步调用它。有了这个举动,
Session
的所有权对象也传输到 boost::asio 内部。
async_read_some
立即返回
start
的所有局部变量和
accept
中的 lambda被摧毁。然而
Session
的所有权已经转移,因此这里没有由于生命周期问题而未定义的行为。
start
,在这种情况下
Session
的所有权将被转移到另一个 lambda 的成员和带有
Session
的 lambda所有权将再次转移到内部 boost::asio 存储。 lambda 异步调用后,会被 boost::asio 销毁。然而,在这一点上,所有权已经转移。
Session
对象最终被销毁,当
if(!errorCode)
失败,并且拥有
std::unique_ptr<Session>
的 lambda在调用后被 boost::asio 销毁。
Session
相关的未定义行为,我认为这种方法没有问题。的一生。如果您使用的是 C++17,那么删除
&&
也很好。在
std::unique_ptr<Session>&& self
范围。
关于c++ - Unique_ptr 将所有权移动到包含对象的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58051387/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!