2016-09-17 8 views
1

Цель, которую я установил для функции std ::, потеряна, я не знаю, почему, возможно, я пропускаю небольшую ошибку в этой программе. Может кто-то помочь.Цель, установленная в std :: function, потеряна

класс Тест регистрирует лямбда в одноэлементном классе, но при попытке вызвать обратный вызов целевой объект в функции std :: теряется.

#include <iostream> 
#include <functional> 

using namespace std; 

class callback_store final 
{ 

    using callback_func_type = std::function<void()>; 

    public: 
    static callback_store instance() 
    { 
     static callback_store instance; 
     return instance; 
    } 

    void register_callback(callback_func_type func) 
    { 
     std::cout << "register_callback() <<<" << std::endl; 
     m_func = func; 

     // I am able to call the targets from here. 
     std::cout << "register_callback() func() " << std::endl; 
     func(); 
     std::cout << "register_callback() m_func() " << std::endl; 
     m_func(); 

     // some stats 
     std::cout << "register_callback() :: " << func.target_type().name() << std::endl; 
    } 

    void invoke_callback() 
    { 
     std::cout << "invoke_callback() <<< " << std::endl; 

     if (!m_func) 
     { 
      // This block is hit! Why 
      std::cout << "invoke_callback() :: m_func empty" << std::endl; 
      return; 
     } 

     return m_func(); 
    } 

    private: 
    callback_func_type m_func; 

}; 


class Test final 
{ 
    public: 
    Test() 
    { 
     callback_store::instance().register_callback([this](){do_test();}); 
    } 

    ~Test() 
    { 
     std::cout << "destructor" << std::endl; 
    } 

    private: 
    void do_test() 
    { 
     std::cout << "do_test() invoked !!" << std::endl; 
    } 

}; 

int main() 
{ 
    cout << "Hello World" << endl; 

    Test t; 

    callback_store::instance().invoke_callback(); 


    return 0; 
} 

Выход:

sh-4.3$ g++ -std=c++11 -o main *.cpp 
sh-4.3$ main 
Hello World 
register_callback() <<< 
register_callback() func() 
do_test() invoked !! 
register_callback() m_func() 
do_test() invoked !! 
register_callback() :: ZN4TestC4EvEUlvE_ 
invoke_callback() <<< 
invoke_callback() :: m_func empty 
destructor 
+2

Ваш одноточечно реализация сломана , но все одноточечные реализации нарушены. Не используйте синглтоны. –

+0

Ваш код никогда не регистрирует ваш обратный вызов. Поскольку ваша функция 'instance()' возвращает временную копию * объекта 'callback_store', ваши регистрационные данные попадают в это временное, которое затем немедленно уничтожается. Фактический «первичный» одноэлементный объект «static callback_store instance» никогда не получает в нем ничего зарегистрированного. – AnT

ответ

6

Я думаю, что проблема в том, как вы реализовали свой одноэлементный класс.

public: 
static callback_store instance() 
{ 
    static callback_store instance; 
    return instance; 
} 

Вы возвращаете копию статического объекта, а вы должны использовать

public: 
static callback_store& instance() 
{ 
    static callback_store instance; 
    return instance; 
} 

И выход кода будет (проверено):

Hello World 
register_callback() <<< 
register_callback() func() 
do_test() invoked !! 
register_callback() m_func() 
do_test() invoked !! 
register_callback() :: ZN4TestC4EvEUlvE_ 
invoke_callback() <<< 
do_test() invoked !! 
destructor 
4

экземпляр() функция член должен возвращать callback_store &

+0

Объяснение было бы неплохо, если бы вы могли добавить один :) Кроме того, вы должны включить дополнительную информацию и, возможно, ссылку на документы? – Rakete1111