|
Free Educational Resource Center for teachers and students. Includes Interviews, Sourcecode, Free Software, Research Papers, Articles, Tutorials and much more.. |
R E S E A R C H A C T I V I T Y . C O M
Our Fellow Research Center for Ph.D Schollars |
|
| Home About Submit & Earn | Archives: C And C + + Programming » Dev Packages » Interviews » Php Mysql Programming » Windows Programming | |
|
C And C Plus Plus Programming > easy cplusplus delegates generic properties closures thunks
Easy C++ - Delegates / Generic Properties / Closures / Thunks Purpose of this document is not to start yet another discussion, but taking implementation of delegates in C++ (which nomrally most of C++ compilers don't support) to one more step ahead. And make it REAL EASY for developers to add such feature to their existing C++ program to compile on any C++ compiler. What are we talking about? We are talking about a member (treated as variable) of certain class that has 2 type of functions associated with, one function that returns the value of certain type when said data member is asked to return a value, and other function to set the value when said data member is assigned a value. Understanding using simple example: Take example of a Button on a dialog, Button is basically a class and has a member called "width". When width is assigned a value the button's width is physically changed on the idalog surface and when we assign this member to an "int" type variable, said "width" property returns the width of the button.
Now, if the data member "width" was a normal integer "int" it wont affect the width of the button physically, so basically we have to create "width" in a way that it should affect button width when assigned a value, and must retun button's physical width when required. For this we need to attach two functions to this member, one function for changing button's width, and other for getting button's width. How to accomplish this? To accomplish this, we will not define data member 'width' as int but define member 'width' someway as property (in other words) a class that has "operator =" , and has 2 functions that we bind to this tiny Button class for getting and setting data value, and performing extra functionality (e.g. affecting button's width). So we need something like:
Question is how to attach the two little member functions 'set_value' and 'get_value' to data member 'width', so that they get called automatically when 'width' is used in either way. Little into depth. This is what keywords, property in Microsoft Visual C++, delegates in C#, and closure in Borland C++ Builder are used. But they are not cross platform and not supported by all C++ compilers. For example (keyword): property not supported by GCC property not supported by Borland C++ closure not supported by GCC closure not supported by Microsoft VC++ property and closure both not supported by Watcom C++ property and closure both not supported by LCC property and closure both not supported by Intel C++ (am not sure about this) To overcome this problem, we have many implementations for generic properties * some use tempaltes * some use hardcoded class name to use with scope resolution operator * some utilize #define keyword, etc etc. SO WHY YET ANOTHER IMPLEMENTATION? keyword "property" is available in MSVC++ only. keyword "closure" is available in Borland C++ only. What about GCC, and compilers on other platforms like Linux and Mac OSX? Using other than (builtin implementations) "property" and "closure", mostly a new class is created for each data member, which becomes bulky. In result it may not affect program speed (depends), but definitely increases final executable size very much. And after all, it is not a good idea to have new class for thousands of data members. In all implementations we have two member functions bound to such properties. But we know that ISO forbids assigning address of member function in a class, in result we have to point to a member function including class scope, such as &Button::*get_value or &Button::*set_value. But, wait, this is specific to class Button, and ofcourse we will end up with templates to resolve this problem. Now question arrives? WHY DO WE BIND MEMBER FUNCTIONS? Because we like our member functions to access all elements of the class (they are in), either public, private, and/or protected. I had an idea last night, WHY NOT USE "friend" FUNCTIONS? (if it has already been implemented, forgive me I neve saw it) A "friend" function has access to all of private, protected, as well as public data. Which will result in more generic class for properties imnplementation. Create a type once and use it multiple times. So, I wrote 2 macros bacially, one that creates the abstract class (not "abstract of c++" I would say a new type), and the other resolves the class pointer from long, using casting "reinterpret_cast". Usage:
Now it is time to bind some "friend" functions
What is this? width.bind( get_width , set_width , (long)this ); We called the function "bind" that is memhber of new property class we created, and then we passed it arguments: 1. getter - get_width 2. setter - set_width 3. pointer to current class to reuse in friend functions COMPULTIONS: 1. First argument of each get and set functions must be "long" which will be used as class pointer. 2. In the set function 2nd argument will be the type of variable "new class type" was created for. 3. Set function must also have return type as property type, even if it is not returning any value. Now implement the boud functions, they can be implemented outside but am implementing them within class for clear idea.
Further summarizing the interpretation portion of the code: CREATE_CLASS_POINTER(Button, cls); instead of using //Button *cls = reinterpret_cast<Button *> (__CP); Compultion: 1. First argument variable name of both get and set functions must be __CP, if you wish to use said "CREATE_CLASS_POINTER" macro, or create your own. USING THIS "Button" CLASS:
Summary of all talk: 1. Cross platform code 2. All C++ compilers supopport 3. Small foot-prints in final executable 4. Not bulky for execution 5. Can be used even if you have no idea what are function pointers and generic properties
IMPLEMENTATION OF "CREATE_CLASS_POINTER" in delegate.h
SAMPLE WINDOWS PROGRAM (changes and retrieves width of a window):
|