是否可以安全地从存储的回调中删除std :: function [重复]

问题描述 投票:1回答:1

我有一个在std::function中存储回调的类,然后执行一些操作,然后将结果通知回调目标。如果目标看到结果无效或不想继续进行工作,它将删除包含std::function回调的调用程序类。

我知道std::function删除后是否不访问其成员,这将是安全的,但我没有看到这样的保证。我所拥有的是,调用者类在调用回调后不会访问其成员,但是回调可以选择再次执行更多工作,在这种情况下,它不会删除调用者。

此示例说明了问题:

using callback = std::function<void(Caller& c, bool failed)>;

class Caller
{
    callback cb;
    bool Work()
    {
        return true;
    }

public:

    Caller(const callback& cb) : cb{ cb } {}

    void DoWork()
    {
        bool result = Work();
        cb(*this, result);
    }

};


int main(int argc, char **argv)
{

    for (int i = 0; i < 1000; ++i)
    {
        Caller *c = new Caller{
            [](Caller& c, bool failed)
        {
            if (failed)
                delete &c;
            else
                c.DoWork();
        }
        };
        c->DoWork();
    }
}

我使用msvc在Windows上编译了代码,并且可以正常工作(或者可能是隐藏的堆损坏?)

我不希望使用其他设计,因为我正在使用的实际代码很复杂,并且调用方类就像是工作器和回调之间的代理,并且是按操作分配的,因此重构代码会很费劲

编辑:我知道这不是最佳的c + +实践,但我正在处理c api,尤其是iocp。我的代码是这样的:io对象(套接字)发出io请求,该请求需要为重叠的结构和op数据分配内存,该结构将保留回调,当op完成时,它将调用该回调,并且如果有错误,回调可能无法继续进行,否则它将发出下一个请求。调用回调后,结构将自行删除,并且从回调开始的新操作将像这样继续。

现在假设我有一个半双工协议的sessionn,例如http,那么一次只有一个操作,因此我可以对所有操作使用相同的结构,而无需再次分配,因此当第二个操作开始时,我破坏了旧的strucutre并在适当的位置构造新的对象,并在第一个structre的回调中完成]

我有一个在std :: function中存储回调的类,然后执行一些操作,然后将结果通知回调目标。如果目标看到结果无效或不想继续...

c++ memory-management
1个回答
0
投票

看起来不错。我将用指针替换回调中的Caller&引用,但这并不重要。

© www.soinside.com 2019 - 2024. All rights reserved.