1. C++ / Говнокод #10475

    −32

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    #pragma once
    
    #include <vector>
    #include <assert.h>
    
    class Obj
    {
    public:
    	virtual ~Obj(void) { }
    };
    
    
    class Sig
    {
    	typedef void (Obj::*slot_t)(void*);
    	mutable std::vector<std::pair<Obj*, Sig::slot_t>> m_connSlots;
    
    public:
    	void operator()(void* arg) const
    	{
    		std::vector< std::pair<Obj *, slot_t> >::const_iterator iter = m_connSlots.cbegin();
    		while(iter != m_connSlots.cend())
    		{
    			Obj * object = iter->first;
    			slot_t slot = iter->second;
    			(object->*slot)(arg);
    			iter++;
    		}
    	}
    
    	template<class obj_T> void connect(obj_T* object, void (obj_T::*slot)(void*)) const
    	{
    		assert(dynamic_cast<Obj*>(object)!=0);
    		m_connSlots.push_back(std::make_pair(reinterpret_cast<Obj*>(object),
    			reinterpret_cast<Sig::slot_t>(slot)));
    	}
    };

    QBicycle

    Запостил: Xom94ok, 30 Мая 2012

    Комментарии (11) RSS

    • показать все, что скрыто
      Ответить
    • показать все, что скрыто
      Ответить
    • А ведь можно было бы сделать, чтобы не требовалось наследование от Obj, да и набор аргументов был гибчее
      Ответить
      • С удовольствием выслушаю прочту идею, если поделитесь :) boost::signal2?
        Ответить
        • раз есть cbegin, значит с++11, значит даже без отмазки на буст (вдруг нежелание), можно использовать std::function/std::bind - условно говоря, просим лишь std::function<void(void *)>, и вот уже от обязательного наследования от Obj избавились
          написав некую шаблонную обвязку по аналогии с function, можно получить на руки все типы R результат, A1..An аргументы, и таким образом не привязываться к тому, что аргументы всегда будут одни и те же
          ну или забить на шаблонную обвязку и сделать operator () темплейтовым с целью сбагривания всего переданного в function

          должно получиться нечто
          my::signal<void(int, float)> sig1;
          someclass smth, smth2;
          sig1.connect(std::bind(&someclass::somemethod, &smth, _2, "text comment", _1));
          sig1.connect(std::bind(&someclass::othermethod, &smth2, _1, _2));
          sig1(10, 20.); // calls smth.somemethod(20., "text comment", 10) + smth2.othermethod(10, 20.);

          за деталями советую посмотреть boost::signals2, работает без всяких moc и даже в С++03

          зы сорри за многочисленные правки
          Ответить
          • Надо было мне заранее уточнить условия. Написано это было действительно на C++11, но в конечном счете будет перенесено в VS.NET 2003.
            И, кстати, я бы рад воспользоваться boost (см. спойлер в предыдущем сообщении :) или написать всё на Qt, да только работа не разрешает пользоваться ни тем, ни другим :(
            Ответить
            • ох уж эти консерваторы. студия 2003 это тоже феерично.
              мы на работу зимой взяли пацана, которому на предыдущем месте работы не разрешали использовать даже stl, не предлагая ничего взамен (в некоторых конторах стл не используется по необходимости запуска кода даже на шреддерах, но это не его случай)
              такие ублюдочные условия труда дискредитируют язык
              Ответить
          • должно получиться даже проще:
            sig1.connect(&someclass::somemethod, &smth, "text comment", _1);

            т.е. bind() спрятать.
            Ответить

    Добавить комментарий