#include <iostream>
#include <list>
#include <functional>
#include <algorithm>

class A
{                                                                                                                                           
    public:                                                                                                                                 
        virtual         void                            link                    (A&)    = 0;                                                
        virtual         void                            link                    (A*)    = 0;                                                
        virtual         std::function<void(int)>        getFunction2SetProperty ()      = 0;                                                
};                                                                                                                                          
                                                                                                                                            
class B: public A                                                                                                                           
{                                                                                                                                           
    public:                                                                                                                                 
        virtual void    prop1           (int i)                                                                                             
        {
          std::cout << "B::" << __func__ << ",i=" << i << std::endl;
          send(i);
        };

        virtual void    link            (A*     those) override
        {
            sendList.push_back          (those->getFunction2SetProperty ());
        };
        virtual void    link            (A&     those) override
        {
            link (&those);
        };

        virtual std::function<void(int)>        getFunction2SetProperty () override
        {
            return std::bind (&B::prop1, this, std::placeholders::_1);
        };


    protected:
        virtual void    send            (int i)
        {
            for (std::function<void(int)>& f : sendList) f(i);
        };

        std::list<std::function<void(int)>>     sendList;
};

class BB: public B
{
    public:
        virtual void    prop1           (int i) override
        {
          std::cout << "BB::" << __func__ << ",i=" << i << std::endl;
          send(i);
        };
};


class C: public A
{
    public:
        virtual void    propInteger     (int i)
        {
          std::cout << "C::" << __func__ << ", i=" << i << std::endl;
            send(i);
        };

        virtual void    link            (A*     those) override
        {
            sendList.push_back  (those->getFunction2SetProperty ());
        };
        virtual void    link            (A&     those) override
        {
            link (&those);
        };

        virtual std::function<void(int)>        getFunction2SetProperty () override
        {
            return std::bind (&C::propInteger, this, std::placeholders::_1);
        };

    protected:
        virtual void    send            (int i)
        {
            for (std::function<void(int)>& f : sendList) f(i);
        };

        std::list<std::function<void(int)>>     sendList;
};

class CC: public C
{
    public:
        virtual void    propInteger     (int i) override
        {
          std::cout << "CC::" << __func__ << ", i=" << i << std::endl;
          send (i);
        };
};

int
main ()
{
    A*          a1 = new BB;
    A*          a2 = new CC;

    a1->link (a2);
    std::function<void(int)>    f = a1->getFunction2SetProperty ();
    f(123);
    delete a1;
    delete a2;

    return 0;
};