What do your think when you see such a structure?
Code:
typedef struct TOOLBOX
{
STRING* name;
int layer;
BOOL cap;
} TOOLBOX;
The right answer is: when you want an instance of a TOOLBOX datatype, you have to initialize it manually. This covers string creation and int & BOOL initialization. If the structure would be bigger or more complex, this task would be quite inconvinient if you do it again and again and again.. I guess this obvious.
When you think of instances, you might of course as well of object oriented programming. One benefit of OOP code is, that you are able to write class-methods which initialize objects when they are created, these are called constructors. You could have tight constructors which initialize the object with default values, but you could also define constructors that allow parameters. You can also override other constructors of an object.. very comfortable. Constructors are also very suitable for defensive programming, which means, that you have fill control what might and might not go wrong.
Unfortunately, liteC is basically derived from C and not from C++, but you can override functions. That is quiet useful! In this case you have to do a lot of stuff to initialize one single object of TOOLBOX and such a programming style inflates your code. Now I want to define some constructors which do the work for me automatically. I want 3 constructors with the following parameterlists:
TOOLBOX* getTOOLBOX (int _nameLength, int _layer, BOOL _cap);
TOOLBOX* getTOOLBOX (int _nameLength);
TOOLBOX* getTOOLBOX ();
This allows me to "just" get an instance (with default values) or I could specify some attributes, like the allowed name length or other attributes. All functions return a ptr to the allocated object, so all function signatures are basically the same as constructors - the only difference is that they arent injected into a class definition.
Ok, the last two constructors are easy:
Code:
//only name length (STRING initialization)
TOOLBOX* getTOOLBOX (int _nameLength) {return(getTOOLBOX(_nameLength, 0, false));}
//all default values
TOOLBOX* getTOOLBOX () {return(getTOOLBOX(64));}
They just call themselves. The very first constructor is a bit more advanced because here we do all the work.
Before I start with that, I show you -without commenting too much- a STRING constructor which allocates a STRING object with the given length:
Code:
//STRING constructor
//Initializes STRING with the given length.
//If length <= 0 a default STRING with 512 characters will be allocated
STRING* getSTRING (int _length)
{
//Format: "#<length>"
STRING* _buffer = "";
str_cpy(_buffer, "#");
//name length check
if (_length > 0) {
STRING* _bufferTemp = "";
str_cat(_buffer, str_for_num(_bufferTemp, _length));
} else {
str_cat(_buffer, "512"); //default length
}
STRING* _target;
_target = str_create(_buffer);
return(_target);
}
It safely creates a STRING with the given length. If _length <= 0 we create a default String with a length of 512 characters.
Ok, back to TOOLBOX:
The following function create a TOOLBOX object and initializes it with the given arguments.
Code:
//full attribute parameters
TOOLBOX* getTOOLBOX (int _nameLength, int _layer, BOOL _cap)
{
TOOLBOX* _temp;
_temp = (TOOLBOX *)malloc(sizeof(TOOLBOX));
_temp->name = getSTRING(_nameLength);
_temp->layer = _layer;
_temp->cap = _cap;
return(_temp);
}
So, how do we use it? Well, just define a pointer to it and create it!
Code:
TOOLBOX* tools;
tools = getTOOLBOX();
Now, you can use it instantly and you don't need to write unnecessary code to initialize it and its safe enough to pass it anywhere, because the constructors build it as safety as you wish. So you could do with the TOOLBOX right after creation this:
Code:
str_cpy(tools->name, "Christian");
error(tools->name);
If you wouldnt use such constructors, you have to do a lot more and you could come across nasty errors.
This is NO substitution for an OOP design, just because liteC is no OOP language, it counts as a defensive programming concept, which you'll learn when you learn OOP (with JAVA for instance).
So I hope you like this text and maybe your code will a bit more advanced now.
Cheers,
Christian