Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在lambda[C+;+;]中捕获此信息的替代方法_C++_C++11_Lambda_This_Shared Ptr - Fatal编程技术网

C++ 在lambda[C+;+;]中捕获此信息的替代方法

C++ 在lambda[C+;+;]中捕获此信息的替代方法,c++,c++11,lambda,this,shared-ptr,C++,C++11,Lambda,This,Shared Ptr,我知道,如果我必须在lambda中调用成员函数进行回调,我会在lambda中捕获这些函数,并且效果很好。 但是我最近看到了一些崩溃,似乎在这个函数所指向的对象已经被破坏之后,成员函数才被访问。 简而言之,在shutdown中,对象被销毁,但指针在lambda中传递,这会被访问并导致崩溃 因此,我试图了解社区在这种情况下通常会做些什么。我找不到太多,但我认为共享ptr可能是一种选择 任何建议/线索都会帮助我理解和实现一个替代方案。 < P> C++中,你负责跟踪对象的生命周期。 这意味着您必须跟踪

我知道,如果我必须在lambda中调用成员函数进行回调,我会在lambda中捕获这些函数,并且效果很好。 但是我最近看到了一些崩溃,似乎在这个函数所指向的对象已经被破坏之后,成员函数才被访问。 简而言之,在shutdown中,对象被销毁,但指针在lambda中传递,这会被访问并导致崩溃

因此,我试图了解社区在这种情况下通常会做些什么。我找不到太多,但我认为共享ptr可能是一种选择


任何建议/线索都会帮助我理解和实现一个替代方案。

< P> C++中,你负责跟踪对象的生命周期。 这意味着您必须跟踪包含指向其他对象的指针和引用的对象的生命周期,并确保它们不会像这些对象那样长寿

你的任务失败了。您传递了lambda,它捕获指向周围对象的指针,就好像它们是糖果一样,而不是直接进入对象内部的直线

通过散布共享指针来解决生命周期问题通常是个坏主意。使对象的生命周期更加模糊可能会减少立即崩溃的事件,但模糊的对象生命周期并不能使程序工作。这个模糊的球要么扩展到包含你的整个程序,而这个程序现在永远也无法真正关闭,要么它自己盘旋,自我延续,泄漏资源

共享指针可以在一些狭窄的情况下使用,在这些情况下,您有一个定义的生命周期关系,最好将其建模为共享所有权。这与“我让对象在其指针之前离开,所以我应该尝试共享指针”完全不同!您有一个对象生存期问题。您可以尝试共享指针。现在您有两个问题:原始对象生存期问题和共享指针问题

回调就是一个需要严格的生存期规则的例子。你回电话多久?你什么时候停?你有多迫切需要回收资源?如何注销回调?等等


我编写了使用共享指针和弱指针的回调系统。它们并不完美。这是我在谷歌上找到的一个。听者存储令牌说“继续跟我说话”,当他们离开时,广播员停止对它的唠叨。

C++中你负责跟踪对象的生命周期。 这意味着您必须跟踪包含指向其他对象的指针和引用的对象的生命周期,并确保它们不会像这些对象那样长寿

你的任务失败了。您传递了lambda,它捕获指向周围对象的指针,就好像它们是糖果一样,而不是直接进入对象内部的直线

通过散布共享指针来解决生命周期问题通常是个坏主意。使对象的生命周期更加模糊可能会减少立即崩溃的事件,但模糊的对象生命周期并不能使程序工作。这个模糊的球要么扩展到包含你的整个程序,而这个程序现在永远也无法真正关闭,要么它自己盘旋,自我延续,泄漏资源

共享指针可以在一些狭窄的情况下使用,在这些情况下,您有一个定义的生命周期关系,最好将其建模为共享所有权。这与“我让对象在其指针之前离开,所以我应该尝试共享指针”完全不同!您有一个对象生存期问题。您可以尝试共享指针。现在您有两个问题:原始对象生存期问题和共享指针问题

回调就是一个需要严格的生存期规则的例子。你回电话多久?你什么时候停?你有多迫切需要回收资源?如何注销回调?等等


我编写了使用共享指针和弱指针的回调系统。它们并不完美。这是我在谷歌上找到的一个。当听众离开时,广播公司会停止对其大声嚷嚷。

这是我处理订阅时使用的模式。使用锁定的
弱ptr
消除了交叉案例的风险

#include <memory>
#include <chrono>
#include <thread>
#include <mutex>

using namespace std::literals;

// some external service that will send us events in a callback.
// normally of course we'd have some means to turn these off too.
// However for this demo we'll ignore that for now
void subscribe_for_events(std::function<void()> f);

struct might_go_away : std::enable_shared_from_this<might_go_away>
{
    static std::shared_ptr<might_go_away> create() {
        auto p = std::make_shared<might_go_away>();
        p->start();
    }

    might_go_away() {}

private: 

    using mutex_type = std::mutex;
    using lock_type = std::unique_lock<mutex_type>;

    // handy helper to deliver a weak pointer to ourselves
    auto weak_self() { return std::weak_ptr<might_go_away>(shared_from_this()); }

    // do startup things here, like subscribing to other services etc
    void start() {
        subscribe_for_events([this, weak = this->weak_self()]
        {
            // don't touch 'this' until we have successfully locked the weak ptr
            if (auto self = weak.lock()) {
                // we know we're alive. the variable 'self' will hold the strong count > 0
                // this is a good place to take locks
                handle_event(lock_type(mutex_));
            }
        });
    }

    void handle_event(lock_type) {
        // do things when notified by some event source.
        // we are safe here. `this` will not go away and we own the mutex 
        // we will release the lock when this function exits through RAII.
        // PLUS, because the lock was moved in, we own it. We can release it early if we wish.
    }

    mutex_type mutex_;
};

这是我用来处理订阅的模式。使用锁定的
弱ptr
消除了交叉案例的风险

#include <memory>
#include <chrono>
#include <thread>
#include <mutex>

using namespace std::literals;

// some external service that will send us events in a callback.
// normally of course we'd have some means to turn these off too.
// However for this demo we'll ignore that for now
void subscribe_for_events(std::function<void()> f);

struct might_go_away : std::enable_shared_from_this<might_go_away>
{
    static std::shared_ptr<might_go_away> create() {
        auto p = std::make_shared<might_go_away>();
        p->start();
    }

    might_go_away() {}

private: 

    using mutex_type = std::mutex;
    using lock_type = std::unique_lock<mutex_type>;

    // handy helper to deliver a weak pointer to ourselves
    auto weak_self() { return std::weak_ptr<might_go_away>(shared_from_this()); }

    // do startup things here, like subscribing to other services etc
    void start() {
        subscribe_for_events([this, weak = this->weak_self()]
        {
            // don't touch 'this' until we have successfully locked the weak ptr
            if (auto self = weak.lock()) {
                // we know we're alive. the variable 'self' will hold the strong count > 0
                // this is a good place to take locks
                handle_event(lock_type(mutex_));
            }
        });
    }

    void handle_event(lock_type) {
        // do things when notified by some event source.
        // we are safe here. `this` will not go away and we own the mutex 
        // we will release the lock when this function exits through RAII.
        // PLUS, because the lock was moved in, we own it. We can release it early if we wish.
    }

    mutex_type mutex_;
};

您可以发布代码片段吗?您可以从
std::enable_shared_from_this
,使用
shared_from_this()
获取共享指针并捕获
std::shared\u ptr
以确保该对象仍处于活动状态,或者捕获
std::weak\u ptr
以检查其是否处于活动状态,然后再执行任何操作。我将创建一个@theyesightim。我们可以得到一个?
[self=*this](){self.f();}
?@KerrekSB在这种情况下,您必须保证类有一个正确的构造函数。情况并非总是如此。当然,也不总是可以将其修改为继承自
std::enable_shared_from_this
。可以发布代码片段吗?可以继承自
std::enable_shared_from_this
,使用
shared_from_this()
获取共享指针并捕获
std::shared\u ptr
以确保该对象仍处于活动状态,或者捕获
std::weak\u ptr
以检查其是否处于活动状态,然后再执行任何操作。我将创建一个@theyesightim。我们可以得到一个?
[self=*this](){self.f();}
?@KerrekSB在这种情况下,您必须保证类有一个正确的构造函数。情况并非总是如此。当然,也不总是可以将其修改为从
std::enable_shared_from_this
继承。锁定的弱\u ptr仍然是消除交叉情况的最可靠和最简单的方法,即订阅者离开,而未完成的回调潜伏在消息队列中。@RichardHodges注意到
广播者