Hi there,
I'm wondering if someone here could show me that what I'm trying to do is any of the following (possibly a combination thereof):
1.) Possible
2.) Impossible
3.) Dumb
My frustration arises from working with the WINAPI. I'm trying to wrap some of the window creating procedures in an object oriented way as best as I can.
The functions involved in these procedures can take any number of parameters, can fail in any number of ways and return different error codes.
The reason this is not in the Windows programming forum is because my problem isn't necessarily exclusive to programming for windows, and because it seems to me like rarely anyone gets help there. I've tried to recreate my problem with a pseudo-code example, and I've tried to keep it as terse as possible. Consider the following code:
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
|
struct Item {
Item() : integer(0) {}
int operator=(int i) {
return integer = i;
}
bool operator==(const int& i) {
return integer == i;
}
int integer;
};
struct Foo {};
Item create() {/*...*/}
//returns a valid Type object when it succeeds
//returns 0 when it fails
bool destroy(Item& item) {/*...*/}
//returns true when it succeeds
//returns false when it fails
bool apply(Item& item, Foo foo) {/*...*/}
//returns true when it succeeds
//returns false when it fails
class ItemContainer {
public :
ItemContainer() {
if ((item = create()) == 0) {//did create() fail?
throw ExceptionCreate();
}
}
~ItemContainer() {
if (!destroy(item)) {//did destroy() fail>
throw ExceptionDestroy();
}
}
void modify() {
Foo foo;
//do things with foo or something
if (!apply(item, foo)) {//did apply() fail?
throw ExceptionApply();
}
}
Item item;
};
|
As you can see, create(), destroy() and apply() take different kinds and numbers of parameters, and also can have different return types. Their return values also vary. This matters because I'd like to do something to the following effect instead:
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
|
class ItemContainer {
public :
ItemContainer() {
WrapperCreate().call();
//somehow, this will need access to 'item', maybe a reference?
//however, create() takes no parameters
}
~ItemContainer() {
WrapperDestroy().call();
//this too will need access to 'item' somehow, but it takes one parameter, namely 'item'
}
void modify() {
WrapperApply().call();
//Again, needs access. Takes two parameters
}
Item item;
};
class WrapperBase {
public :
WrapperBase() {}
virtual void call() = 0;
};
class WrapperCreate : public WrapperBase {
public :
WrapperCreate() {}
void call() {
//how to go about calling create()?
if (/*create() fails*/) {
throw ExceptionCreate();
}
}
};
/*Other wrappers*/
|
The pseudo-code isn't even entirely complete, because I'm not quite sure how to express my problem. Basically, I'd like to wrap the function calls and and the exception throwing to these classes, but the functions in question take a varying number of parameters, sometimes with different types, and sometimes they return objects that the ItemContainer class would need to know about or keep track of, in the same way that, for instance, the WINAPI function 'CreateWindow' returns a handle to a window (Which a window class would need to keep track of) - but it could also return NULL should it fail - while another WINAPI function such as 'DestroyWindow' returns a BOOL, and takes a window handle parameter.
Considering all this, is it possible to use a 'WrapperBase' class in the way that I'm trying to? I'm sorry if I didn't explain myself clearly.
Thanks.