简体   繁体   中英

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

So I am writing a project for an OOP course. I came across this peculiarity. I have a class with a customizable function, as such:

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

If in main I am to do the following

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

It will invariable will cause the following error:" Unhandled exception at 0x75284192 in lambda expression.exe: Microsoft C++ exception: std::bad_function_call at memory location 0x0058F710."

And going into debug autos I can see that it read the action as "empty".

however, switching the order as such

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

or using the shared pointer to call add_action():

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

both work fine! (print "hello world")

Note: the normal pointer counterpart to this code does not work in either of these cases.

Does anyone know what could cause this? I am going to look into it but seems to rather subtle. If I find the reason why I shall post it on this thread. Thank you!

Working in Visual Studio 2019 version 16.4.3

foo obj= foo();

obj is constructed by default constructor, so there is no a target in std::function .

By

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

you create new instance of Foo on a heap, whose lifetime is managed by smart pointer sp . This newly created Foo object has also no a target in std::function , because obj didn't have target when copying operation was performed. Foo(const Foo&) just copied empty function.

After construction of sp , these two Foo instances are completely unrelated. By accessing sp you don't modify obj , and vice versa. So obj.add_action could not update std::function of Foo constructed by shared_ptr .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM