Неправильный вызов функции при вызове указателя на функцию-член от указателя на объект - PullRequest
0 голосов
/ 23 апреля 2020

Итак, я пишу проект для курса 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();

Это неизменно приведет к следующей ошибке: «Необработанный исключение в 0x75284192 в лямбда-выражении.exe: Microsoft C ++ исключение: std :: bad_function_call в ячейке памяти 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»)

Примечание: обычный указатель-аналог этого кода не работает ни в одном из этих случаев.

Кто-нибудь знает, что может вызвать это? Я собираюсь разобраться в этом, но кажется довольно тонким! Если я найду причину, почему я опубликую это в этой теме. Спасибо!

Работа в Visual Studio 2019 версии 16.4.3

1 Ответ

0 голосов
/ 23 апреля 2020
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.

...