2010/07/26

Implementing Objective-C Delegation in C++

Sometimes I wan't to implement things like I would do it in Objective-C when working in C++. But in C++ there is no such a thing like delegation. (At least not with that name)
These are just a few notes on how to implement a delegate or delegation in C++. Is not complicated at all the only thing you need is to find the equivalents for Protocols, Delegates, in C++.

Note1: There are no protocols in C++ but you can use interfaces and multi-inheritance to accomplish this.
For example in Objective-C, let's suppose you write something like this:


@protocol UITableViewDataSource;
@interface UITableView : UIScrollView{
@private
    id<UITableViewDataSource  _dataSource;
}
@end

and


@protocol UITableViewDataSource;
@required
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;
@end

Then (assuming you have the same class names) in C++ you will write something like this:

class UITableViewDataSource;
class UITableView : public UIScrollView {
    UITableViewDataSource *_dataSource;
};

class UITableViewDataSource{
    virtual NSInteger tableViewNumberOfRowsInSection(UITableView* tableView, NSInteger section);
}

So, how you implement your protocol?
In Objective-C:


@class MyDataSource <UITableViewDataSource> {
    NSArray *array;
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section;
@end

@implementation MyDataSource
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
    return [array count];
}
@end


In C++ (Assuming there is a NSArray class in c++)


class MyDataSource : public UITableViewDataSource {
    NSArray *array;
    virtual NSInteger tableViewNumberOfRowsInSection(UITableView* tableView, NSInteger section);
};


NSInteger MyDataSource::tableViewNumberOfRowsInSection(UITableView* tableView, NSInteger section){
    return array->count();
}


In C++ multi-inheritance is allowed so could have a controller class that is a controller and also implements UITableViewDataSource interface. (Or in Objective-C words: conforms to UITableViewDataSource protocol)

If in Objective-C you have:


@class TableViewController : UIViewController < UITableViewDataSource > { ...


in C++ you will have:


class TableViewController : public UIViewController, public UITableViewDataSource { ...


Multi-inheritance + interfaces plays quite the same role as protocols.

Note2: There are no selectors in C++ but you can pass a method as a pointer. This is useful when you want  to set a method to be called by other object.
TODO: add samples: for [object performSelector:@selector(aMethod:) withObject:argument afterDelay:0.0];
TODO: add samples for method pointers in C++


Note3: C++ does not bring any kind of concurrency APIs so you will have get your own. Boost thread, OpenCL, CUDA, OpenMP. I think OpenMP is the simplest option here. Most compilers implement it and just with a few lines of #pragma you are done. But if you get really serious and need not only multithreading but also GPU/CPU power then OpenCL is the best option,  OpenCL is a young but powerful bunch of APIs for multi GPU/CPU programming, version 1.1 was just approved by Khronos group last month and with this new update we are able to run c++ code in it. The bad thing is we have to wait until Apple or your hardware vendor implements since OpenCL is just a specification.

TODO:add some links to OpenMP and Boost examples
TODO: add some links to OpenCL

0 comments :