所以我正在为一个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();
}
};
如果在main中我要做以下事情
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();
它必然会导致以下错误:" Unhandled exception at 0x75284192 in lambda expression.exe: Microsoft C++异常。std::bad_function_call 在内存位置0x0058F710。"
而进入debug autos,我可以看到它将动作读作 "空"。
然而,切换顺序为
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")
注意:在这两种情况下,正常的指针对应的代码都不能工作。
有谁知道什么原因会导致这种情况?我打算研究一下,但似乎相当微妙!如果我找到了原因,我将把它发布在这个帖子上。谢谢您!谢谢您
在Visual Studio 2019版本16.4.3中工作。
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
的 Foo
所建 shared_ptr
.