0

所以我正在为 OOP 课程编写一个项目。我遇到了这种特殊性。我有一个具有可自定义功能的类,例如:

#include<memory>  
#include<functional>
#include<iostream>
class foo 
{
private:
   std::function<void()> action = nullptr;
public:
    foo() = default;
    void add_action(std::function<void()> lambda_expression)
    {
        action = lambda_expression;
    }
    void do_action() 
    {
        action();
    }
};

如果主要我要执行以下操作

std::shared_ptr<foo> sp;
{
    foo obj= foo();
    sp = std::make_shared<foo>(obj);
    obj.add_action([]() {std::cout << "hello world" << std::endl; });
}
sp->do_action();

它将始终导致以下错误:“ lambda expression.exe 中 0x75284192 处的未处理异常:Microsoft C++ 异常:内存位置 0x0058F710 处的std:: bad_function_call。”

进入调试汽车,我可以看到它将动作读取为“空”。

但是,像这样切换顺序

obj.add_action([]() {std::cout << "hello world" << std::endl; });
sp = std::make_shared<foo>(obj);

或使用共享指针调用 add_action():

sp = std::make_shared<foo>(obj);
sp->add_action([]() {std::cout << "hello world" << std::endl; });

两者都工作正常!(打印“你好世界”)

注意:与此代码对应的普通指针在这两种情况下都不起作用。

有谁知道这可能是什么原因?我要调查它,但似乎相当微妙!如果我找到了将其发布在此线程上的原因。谢谢!

在 Visual Studio 2019 版本 16.4.3 中工作

4

1 回答 1

0
foo obj= foo();

obj是由默认构造函数构造的,所以std::function.

经过

sp = std::make_shared<foo>(obj);

您在堆上创建新实例Foo,其生命周期由智能指针管理sp。这个新创建Foo的对象在 中也没有目标std::function,因为obj执行复制操作时没有目标。Foo(const Foo&)只是复制了空函数。

构造后sp,这两个Foo实例完全不相关。通过访问sp你不修改obj,反之亦然。因此obj.add_action无法更新构造std::function的.Fooshared_ptr

于 2020-04-23T20:44:59.907 回答