Given:
struct objStruct {
int id;
int value;
};
typedef struct objStruct Object;
Is there a shortcut to allocate and initialize the object, someth开发者_JS百科ing like a C++ constructor?
It could even be a preprocessor macro. Whatever makes the code shorter and more readable than this:Object *newObj = malloc(sizeof(Object));
// successful allocation test snipped
newObj->id = id++;
newObj->value = myValue;
In C I typically create a function in the style of a constructor which does this. For example (error checking omitted for brevity)
Object* Object_new(int id, int value) {
Object* p = malloc(sizeof(Object));
p->id = id;
p->value = value;
return p;
}
...
Object* p1 = Object_new(id++, myValue);
In C99 and beyond, you can use a compound literal, which looks like a cast followed by an initializer in braces:
int init_value = ...;
int init_id = ...;
Object newObj1 = (Object){ .value = init_value, .id = init_id };
Object newObj2 = (Object){ .id = init_id, .value = init_value };
The latter two lines achieve the same effect - the order of the fields is not critical. That is using 'designated initializers', another C99 feature. You can create a compound literal without using designated initializers.
In C it is possible to declare an inline function with the same name as structure:
struct my
{
int a;
};
inline struct my* my(int* a)
{
return (struct my*)(a);
}
//somewhere in code
int num = 123;
struct my *sample = my(&num);
//somewhere in code
It looks pretty similar to C++ ctors.
struct thingy {
char * label;
int x;
};
#define declare_thingy( name, label, val) struct thingy name = { label, val }
struct thingy * new_thingy(const char * label, int val) {
struct thingy * p = malloc(sizeof(struct thingy));
if (p) {
p->label = label;
p->val = val;
}
return p;
}
You really have to distinguish initialization of static
or auto
variables and dynamic allocation on the head. For the first, do named initializers, for the second a well specified init function.
All that can be nicely
packed into macros do give you an easy static/auto
intialization and something similar to new
in C++.
If you are looking for an object oriented "emulation" over C, I strongly recommend the GObject Type System [1], it's mature and largely used by GTK for instance.
GLib [2] has also a nice slice allocator for small objects, currently used by GNOME.
[1] GObject Reference Manual
[2] GLib Memory Slices
精彩评论