build events like anothers languages

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class test
{
   private:
       string name="";
   public:
       event void changedname();
       void setname(string value)
       {
            name=value;
       }
       string getname()
       {
            return name;
       }
};

test a, b;

void a::changed()
{
    cout <<"name from variable 'a' was changed" << endl;
}

void b::changed()
{
    cout <<"name from variable 'b' was changed" << endl;
}


i get error about 'a' and 'b' not be a class. but using a template can i validate these code?
my problem is that i don't know how to use objects outside of functions:(
these is polymorphism, but not accepted by C++:(
Last edited on
closed account (o3hC5Di1)
Hi there,

a and b are not classes, they are objects of class test. Think of it this way: Classes are blueprints, like a plan for a house. The blueprint however is not a house in itself, someone needs to actually build the house according to the blueprint. The same with classes:

1
2
3
4
5
6
class house
{
    //definition of what a house looks like
};

house my_house; //create an actual house-object 



Furthermore, to use polymorphism you will need to derive class a and b from class test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct test
{
    void changed()
    {
        std::cout << "Base test changed";
    }
};


struct a : public test //inherit from test
{
    void changed() //overloading changed()
    {
        std::cout << "Derived A changed";
    }
};



struct b : public test //inherit from test
{
    void changed() //overloading changed()
    {
        std::cout << "Derived B changed";
    }
};



Also, polymorphism only works with pointers. More information:
http://www.cplusplus.com/doc/tutorial/classes/
http://www.cplusplus.com/doc/tutorial/inheritance/
http://www.cplusplus.com/doc/tutorial/polymorphism/


Hope that helps.

All the best,
NwN
1 question: can i transform 'a' and 'b' in static?
> build events like anothers languages

In practice, we would use a library. For instance, Boost.Signals2.
http://www.boost.org/doc/libs/1_54_0/doc/html/signals2.html#idp164786720

If we want a home-grown implementation, a crude outline could be along these lines:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <functional>
#include <vector>
#include <iostream>
#include <memory>

template < typename CB > struct event
{
    std::vector< std::function<CB> > call_back ;

    template < typename FN > event<CB>& operator+= ( FN fn )
    {
       call_back.emplace_back(fn) ;
       return *this ;
    }

};

struct test
{
    const std::string& name() const { return name_ ; }

    void name( const std::string& new_name )
    { name_ = new_name ; fire_name_changed() ; }

    event< void( const test&, const std::string& ) > name_changed ;

    template < typename FN, typename... ARGS > void subscribe( FN fn, ARGS&&... args )
    {
        using namespace std::placeholders ;
        name_changed.call_back.emplace_back( std::bind( fn, args..., _1, _2 ) ) ;
    }

    private:

         std::string name_ = "anonymous" ;

         void fire_name_changed()
         { for( const auto& f : name_changed.call_back ) f( *this, name() ) ; }
};

void a_function( const test& sender, const std::string& value )
{
    std::cout << "a_function: -\n    name of object at "
               << std::addressof(sender) << "  changed to: '" << value << "'\n\n" ;
}

void another_fun( const std::string& msg, const test& sender, const std::string& value )
{
    std::cout << "another_fun: -\n    msg: '" << msg
               << "'\n    sender: " << std::addressof(sender)
               << "\n    value: '" << value << "'\n\n" ;
}

int main()
{
    test t ;
    t.name_changed += []( const test& sender, const std::string& value )
                      {
                          std::cout << "lambda: -\n    name of object at "
                                     << std::addressof(sender)
                                     << "  changed to: '" << value << "'\n\n" ;
                      } ;

    t.name_changed += a_function ;

    t.subscribe( another_fun, "**** name of object is changed! ****" ) ;

    struct recvr
    {
        void handle_it( const test& sender, const std::string& value ) const
                      {
                          std::cout << "recvr::handle_it -\n    name of object at "
                                     << std::addressof(sender)
                                     << "  changed to: '" << value << "'\n\n" ;
                      }
    };

    recvr r ;
    t.subscribe( &recvr::handle_it, r ) ;

    t.name( "Cambalinho" ) ; // change the name to test it
}

http://ideone.com/OBmXFf
closed account (o3hC5Di1)
I just wanted to say thanks for that JLBorges, very informative as always.
Good use of C++11 <functional> too :)

NwN
NwN: heres the code updated:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class person
{
private:
    string name;
public:
    void changed();
    person()
    {
        Name.setContainer(this);
    }
    void setname(string value)
    {
        name=value;
        changed();
    }

    string getname()
    {
        return name;
    }
    //property <person,string,&person::setname,&person::getname> Name;
};


class Joana : public person //inherit from test
{
    static void changed() //overloading changed()
    {
        std::cout << "hello ";
    }
};

but the changed() function give me an error:(
can you explain to me these error please?
"C:\Users\Joaquim\Documents\CodeBlocks\testevents\main.cpp|21|undefined reference to `person::changed()'|"
sorry JLBorges, but your code is very complex:(
but thank you
i love be more simple and for my new language is better be more simple
NwN: finally works fine. i mistake something;)
i must use virtual functions for polymorphism:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include "test.h"
#include <string>
#include <sstream>

using namespace std;

class person
{
private:
    string name;
public:
    virtual void changed()
    {
        cout <<"";
    }
    person()
    {
        Name.setContainer(this);//these is from my property header file
    }
    void setname(string value)
    {
        name=value;
        changed();
    }

    string getname()
    {
        return name;
    }
    property <person,string,&person::setname,&person::getname> Name;//these is from my property header file
};

class joana : public person
{
    void changed()
    {
        cout << "joana name changed" << endl;
    }
}joana;

class ana : public person
{
    void changed()
    {
        cout << "ana name changed" << endl;
    }
}ana;

int main()
{

    joana.Name="ana";
    cout <<(string) joana.Name<< endl;
    ana.Name="joana";
    cout <<(string) ana.Name<< endl;
    return 0;
}

strange using an object name with class name... but works;)
i think that i can't be more simple than that.
Last edited on
anotherthing that i want share:
you need a class that don't need any object???

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class person2
{
private:
    string name;
public:
    void changed()
    {
        cout <<"hello " << name << endl;
    }
    person2()
    {
        Name.setContainer(this);//these is from my property header file
    }
    void setname(string value)
    {
        name=value;
        changed();
    }

    string getname()
    {
        return name;
    }
    property <person2,string,&person2::setname,&person2::getname> Name;//these is from my property header file
}person2;//see the object name igual to class;) 

it's a nice thing;)
> sorry JLBorges, but your code is very complex:(
> i love be more simple and for my new language is better be more simple

Yeah. I looked at the thread title 'events like anothers languages', glanced at a bit of NwN's post and then posted my reply. If I were a bit less hasty, read the complete text of your post, I would have realized that my reply was not what you were looking for. (Though, as it turned out in the end, it wasn't a complete waste - NwN found some value in it.)


> strange using an object name with class name... but works;)

The name of a variable can hide the name of a class (or enum) which is in the same scope.
It can be any variable, not just an object of the same type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// name of the class is 'person'
class person
{
    // ...
};

// the name of a variable can hide the name of a class (or enum) in the same scope
int person = 234 ; // name of variable 'person' hides the name class person

int main()
{
    person = 6 ; // fine; refers to the variable person; class person is hidden


    // person some_person ; // *** error, 'person' referes to the variable, not the class


    // the elaborated-type-specifier clarifies that it is the class person,
    // (not the variable person which is in the same scope)
    class person some_person ; // fine
}
yah.. very strange... maybe now i can do a better class in my new language and convert it to C++ more easy;)
strange question: if C++ is so powerfull why don't use properties and events directly(with it's own functions)?
Last edited on
closed account (o3hC5Di1)
Hi,

You could reverse the question: C++ is powerful because it doesn't push you to use its built-in events system. It gives you the tools you need to build your own, or allows you to use any number of libraries that you wish.

All the best,
NwN
hi... thanks for correct me;)
that's true. and it's because it have less keywords than another languages;)
Topic archived. No new replies allowed.