使用unique_ptr实现回调时,VC ++报告在运行时崩溃

时间:2018-11-25 18:40:29

标签: c++ c++11 visual-c++

我需要使用另一个类的unique_ptr实现回调方法:

#include <iostream>
#include <functional>
#include <memory>
#include <vector>

class A
{
public:
void Show(std::vector<int> a, int b) {std::cout << "Hello " << " " << b << std::endl;}
};

class B
{
public:
void SetCB(std::function<void(std::vector<int> ,int)> callb);
std::function<void(std::vector<int> ,int)> cb;
};

void B::SetCB(std::function<void(std::vector<int> ,int)> callb)
{
cb= callb;
}

int main()
{
std::unique_ptr<A> a1 = std::make_unique<A>();
std::unique_ptr<B> b1 = std::make_unique<B>();
b1->SetCB([&](std::vector<int> a, int b){a1->Show(a,b);});
std::vector<int> y;
b1->cb(y,4);
}

我在VC ++中遇到运行时读取访问错误冲突-我们如何使用带有std :: bind或其他方式的某些参数的unique_ptr来实现回调?

$ c++ -std=c++14 try68.cpp

                 ^

是否无法使用unique_ptr设置回调方法?

1 个答案:

答案 0 :(得分:0)

一个建议,使用lambda回调(通过引用捕获局部变量)时,您应该非常小心。如果您的回调是从a1变量的范围返回的(这是main()函数,那么您的示例就可以了),则表达式a1->Show(a,b)将触发未定义的行为,因为a1悬空参考。如果您的回调函数处于捕获的变量范围之内,那么您的代码就可以了,但是如果您需要传递回调,则必须通过移动以下内容来捕获a1

b1->SetCB([ptr=std::move(a1)](std::vector<int> a, int b){ptr->Show(a,b);};

然后,您的回调函数将获得a1所指向的对象的所有权。