从指向对象的指针调用成员函数指针时调用错误的函数

Bad function call in calling member function pointer from pointer to an object

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

#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++ 异常:std::bad_function_call at内存位置 0x0058F710."

然后进入调试汽车,我可以看到它将操作读取为 "empty"。

但是,这样调换顺序

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; });

两者都很好! (打印"hello world")

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

有谁知道是什么原因造成的?我要调查它,但似乎相当微妙! 如果我找到我应该 post 的原因,请在此线程上。 谢谢!

正在使用 Visual Studio 2019 版本 16.4.3

foo obj= foo();

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

中没有target

来自

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

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

在构建sp之后,这两个Foo实例完全没有关联。通过访问 sp,您不会修改 obj,反之亦然。因此 obj.add_action 无法更新由 shared_ptr.

构造的 Foostd::function