![]() |
Languages »
C / C++ Language »
Delegates
Intermediate
License: The Code Project Open License (CPOL)
C++ Delegates and Borland's C++ Builder Event Handling - Part IBy Mohammad.NasimDescribes how Borland could bybass standard C++ restrictions via __closure keyword |
C++, Dev, Design
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
This article is partitioned into two main parts.
Part I discusses standard C++ member-function-pointers (MFP), which is different from normal function-pointers. It also illustrates the restrictions on these type of pointers and how Borland's C++ Builder bypasses them via its special type of MFP __closure.
Part II shows an application of using this type of MFP. It explains in detail how Borland uses their own type of MFP to handle Windows Events and how it is fascinating rather MFC style or Win32 API style.
I assume that the reader has enough background in order to use MFP. I know its syntax is a little stupid, but I didn't explain it in details. Instead I used comments to explain what lines of code do.
Also, I assume that the reader is aware of Inheritance and polymorphism.
Closures are a very useful feature in C++ builder. To illustrate this, let's talk first about normal member-function-pointers in C++.
Try the following code:
#include <stdlib.h>
class Base{public:int baseFunc(int){}};
class Drvd:public Base{public:int drvdFunc(int){}};
class Alone{public:int aloneFunc(int){}};
//----------------------- Normal member-function-pointers ---------------
int main() {
int (Base::*funcPtr)(int); // MFP of type Base::*
funcPtr = &Drvd::baseFunc; // member-function pointed to
Drvd ob; // type of calling object
(ob.*funcPtr)(2); // calling of MFP is from here
system("pause");
return 0;
}
This code shows the behavior of normal C++ member-function-pointers (MFP).
As we see, MFP of type Base::* can point to the following:
Base::baseFunc - and can be called from object of type Base/Drvd. Drvd::baseFunc - and can be called from object of type Base/Drvd. Drvd::drvdFunc Alone::aloneFunc If we changed MFP’s type to be Drvd::*, the situation is going to be changed slightly to point to:
Base::baseFunc - and can be called form object of type DrvdDrvd::baseFunc - and can be called from object of type Drvd Drvd::drvdFunc - and can be called from object of type Drvd But, it cannot point to:
Alone::aloneFunc Finally if our MFP be of type Alone::*, it can only point to:
Alone::aloneFunc - and can be called from object of type Alone And it cannot point to:
Base::baseFunc Drvd::baseFunc Drvd::drvdFunc Borland has added a new keyword to language to bypass restrictions set by the standard C++.
This keyword is __closure.
So far we have three restrictions that are:
Base cannot point to Drvd member-functions that are new (not inherited). Base/Drvd and Alone for example. Class::member-function. This would be very useful if solved, since objects may change polymorphically at run-time. Actually the first and the second restrictions are very similar. In other words our goal is to make any MFP point to any member-function in any class that is either in the inheritance hierarchy or not.
Let’s see how Borland solved this problem using the __closure keyword.
#include <stdlib.h>
class Base{public:int baseFunc(int){}};
class Drvd:public Base{public:int drvdFunc(int){}};
class Alone{public:int aloneFunc(int){}};
//---------------------- Borland's C++ Buildre's Closures ---------------
int main() {
int ( __closure *funcPtr)(int); // special MFP of type __closure
Drvd ob;
funcPtr = ob.drvdFunc; // member-function pointed to
funcPtr(2); // calling of closure is from here
system("pause");
return 0;
}
Try to point funcPtr to any member function and see the result. Just make sure that it has the same parameters list and and the same return type.
Now let’s see how solving the third problem would be very useful. Check out this code:
#include <iostream.h>
class Base{public:virtual int baseFunc(int){cout << "i am baseFunc in Base class\n" ; }};
class Drvd:public Base{public:int baseFunc(int)
{cout << "i am baseFunc in Drvd class\n" ; }};
//---------------------- Borland's C++ Buildre's Closures ---------------
int main() {
int ( __closure *funcPtr)(int); // special MFP of type __closure
Base *ob = new Base();
funcPtr = ob->baseFunc; // member-function pointed to
funcPtr(2); // calling of MFP is from here
delete ob;
ob = new Drvd(); // polymorphic behaviour
funcPtr = ob->baseFunc;
funcPtr(2);
delete ob; ob=NULL;
system("pause");
return 0;
}
Isn’t this great? Thank you Borland.
See you in Part II.
| You must Sign In to use this message board. | ||||||||
|
||||||||
|
||||||||
|
||||||||
|
||||||||
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 26 Nov 2009 Editor: Deeksha Shenoy |
Copyright 2009 by Mohammad.Nasim Everything else Copyright © CodeProject, 1999-2010 Web17 | Advertise on the Code Project |