- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我经常在代码中看到这种模式,将 shared_from_this
作为第一个参数绑定(bind)到成员函数并使用 async_*
函数调度结果。这是另一个问题的示例:
void Connection::Receive()
{
boost::asio::async_read(socket_,boost::asio::buffer(this->read_buffer_),
boost::bind(&Connection::handle_Receive,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
使用 shared_from_this()
而不是 this
的唯一原因是在调用成员函数之前保持对象处于事件状态。但除非在某处有某种 boost 魔法,因为 this
指针的类型是 Connection*
,这就是 handle_Receive
可以采用的所有内容,而 smart返回的指针应立即转换为常规指针。如果发生这种情况,则没有任何东西可以使对象保持活力。当然,调用 shared_from_this
时没有指针。
但是,我经常看到这种模式,我不敢相信它会像我认为的那样完全被打破。当操作完成时,是否有一些 Boost 魔术导致 shared_ptr 稍后转换为常规指针?如果是这样,这是否记录在某处?
特别是,它是否在某处记录了共享指针将保持存在直到操作完成?在强指针上调用 get_pointer
然后在返回的指针上调用成员函数是不够的,除非强指针直到成员函数返回才被销毁。
最佳答案
简而言之,boost::bind
创建 boost::shared_ptr<Connection>
的拷贝从 shared_from_this()
返回, 和 boost::asio
可以创建处理程序的拷贝。处理程序的拷贝将保持事件状态,直到发生以下情况之一:
run()
所在的线程调用。 , run_one()
, poll()
或 poll_one()
成员函数已被调用。io_service
被销毁了。io_service::service
拥有处理程序的通过 shutdown_service()
关闭.以下是文档的相关摘录:
boost::bind documentation :
The arguments that
bind
takes are copied and held internally by the returned function object.
boost::asio io_service::post
:
The
io_service
guarantees that the handler will only be called in a thread in which therun()
,run_one()
,poll()
orpoll_one()
member functions is currently being invoked. [...] Theio_service
will make a copy of the handler object as required.
boost::asio io_service::~io_service
:
Uninvoked handler objects that were scheduled for deferred invocation on the
io_service
, or any associated strand, are destroyed.
Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), ashared_ptr
to the object would be bound into the handlers for all asynchronous operations associated with it. [...] When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and allshared_ptr
references to the objects are destroyed.
虽然日期为 (2007),但 Networking Library Proposal for TR2 (Revision 1)源自 Boost.Asio。栏目5.3.2.7. Requirements on asynchronous operations
为 async_
的参数提供了一些详细信息功能:
In this clause, an asynchronous operation is initiated by a function that is named with the prefix
async_
. These functions shall be known as initiating functions. [...] The library implementation may make copies of the handler argument, and the original handler argument and all copies are interchangeable.The lifetime of arguments to initiating functions shall be treated as follows:
- If the parameter is declared as a const reference or by-value [...] the implementation may make copies of the argument, and all copies shall be destroyed no later than immediately after invocation of the handler.
[...] Any calls made by the library implementation to functions associated with the initiating function's arguments will be performed such that calls occur in a sequence call1 to calln, where for all i, 1 ≤ i < n, calli precedes call i+1.
因此:
shared_ptr<Connection>
的拷贝,增加 Connection
的引用计数实例,而 handler 的拷贝仍然存在。io_serive::service
时未完成,则会发生这种情况。正在关闭或 io_service
被摧毁。在示例中,处理程序的拷贝将被销毁,从而减少 Connection
的引用计数。 ,并可能导致 Connection
要销毁的实例。Connection
的引用计数。 ,并可能导致其被破坏。asnyc_
相关的函数的参数,将按顺序执行,而不是并发执行。这包括 io_handler_deallocate
和 io_handler_invoke
.这保证了在调用 handler 时不会释放 handler。在 boost::asio
的大部分地区实现时,处理程序被复制或移动到堆栈变量,一旦执行退出声明它的 block ,就允许销毁发生。在示例中,这确保了 Connection
的引用计数在调用 handler 期间将至少为 1。关于c++ - boost async_* 函数和 shared_ptr 的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11356742/
使用 shared_ptr 时,我应该只使用 shared_ptr 吗?申报一次或申报shared_ptr无论我经过哪里? 所以在我新建实例的函数中,我将它包装在 shared_ptr 中但是当我从函
#include #include #include using namespace std; struct Node { Node(int data, boost::shared_pt
对于我目前正在处理的代码,我们有时需要使用较旧的编译器在一些较旧的系统上进行编译(例如,我们在较旧的 IBM BlueGene/L 上运行 sims,其支持契约(Contract)规定了一些非常旧的
我正在阅读 this answer作者指的是boost best practices其中说: Avoid using unnamed shared_ptr temporaries to save ty
我正在处理几个类,我想知道如何在我的应用程序类中使用普通成员,而该成员需要使用 shared_from_this()? 这里有一些代码来阐明我的意思(见评论) class Observable { p
我有一个 Foo 类,其中包含一个 Hotel 类 的 shared_ptr,以及一个 Rules 类(位于 namespace Rules 内): class Foo { public: //
我想不通。看起来我遗漏了一些简单的东西?我要在 MakePointToSameValue 中输入什么,以便在点 (1) b.ptr 和c.ptr 与a.ptr 指向同一个 换句话说,a.ptr.get
我已尽我所能制作了 SSCE。我怀疑共享指针在我在 main 中请求它们之前解构(释放)了我的对象。如何在不完全绕过共享指针的情况下防止这种情况发生?这是一个程序中的孤立问题,否则可以通过使用 sha
这个问题在这里已经有了答案: Set shared_ptr with new_pointer that is old_pointer + offset (1 个回答) 关闭 4 年前。 我目前正在学
假设我们有一个类,成员如下 std::map> member_我们无法替换 member通过具有 std::shared_ptr 的 map ,因为该类必须对 ObscureType 的非常量函数进行
我正在用 C++ 做学校作业(我还在学习)。我正在尝试实现随机生成的二叉树结构,使用 shared_ptr 在多个地方存储节点的信息(我需要它作为作业)。考虑以下示例代码(这是我的小测试程序): #i
我有以下类(class) struct Images { std::vector > ptr_vector; } 将 ptr_vector 放入 std::shared_ptr 中不会在复制
我刚刚对一个项目进行了大规模重构,添加了一个基类来代替现在所说基类的派生类(因为我想要这个类的更多“类型”)。 我的问题是,一些实用函数将原始类 A 的引用作为 shared_ptr,因此函数声明如下
我记得 Scott Meyers 教我的 func(shared_ptr(new P), shared_ptr(new Q)); 是危险的,因为(如果我没记错的话)内存分配、引用计数(构造)和分配给
给定 struct X { void f(std::shared_ptr); }; auto x(std::make_shared()); 我大概可以安全地做 x->f(std::move(x
我试着介绍了一些const一些新代码的正确性(实际上是功能范例),发现我无法传递 std::shared_ptr到一个需要 std::shared_ptr 的函数.请注意,我不想放弃 constnes
我需要将原始指针包装到 shared_ptr 中,以便将其传递给函数。该函数在返回后不保留对输入对象的任何引用。 { MyClass i; shared_ptr p(&i); f(p);
我在继承链中有4个类:A-> B-> C,A-> B-> D,其中B是唯一的类模板。 我想拥有一个在id和对象指针(C或D)之间映射的std::map,但是我在将make_shared输出分配给std
boost::shared_ptr 是否解决原始指针问题? Base* p = new Base(); shared_ptr sp(p); shared_ptr sq(p); 两个 shared_
How can shared_ptr be a subclass of shared_ptr? 我想知道如何实现模板类 C这样 C是 C 的子类? 我已经观察到上述情况,例如 shared_ptr和
我是一名优秀的程序员,十分优秀!