假设:
struct objStruct {
int id;
int value;
};
typedef struct objStruct Object;
是否有分配和初始化对象的快捷方式,如C ++构造函数? 它甚至可以是预处理器宏。无论是什么使代码更短,更可读:
Object *newObj = malloc(sizeof(Object));
// successful allocation test snipped
newObj->id = id++;
newObj->value = myValue;
答案 0 :(得分:44)
在C中,我通常以构造函数的方式创建一个函数来执行此操作。例如(为简洁起见,省略了错误检查)
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);
答案 1 :(得分:22)
在C99及更高版本中,您可以使用复合文字,它看起来像一个强制转换,后跟括号中的初始值设定项:
int init_value = ...;
int init_id = ...;
Object newObj1 = (Object){ .value = init_value, .id = init_id };
Object newObj2 = (Object){ .id = init_id, .value = init_value };
后两行达到相同的效果 - 字段的顺序并不重要。那是使用'指定初始值设定项',另一个C99功能。您可以在不使用指定初始值设定项的情况下创建复合文字。
答案 2 :(得分:6)
在C中,可以声明一个与结构名称相同的内联函数:
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
它与C ++ ctors非常相似。
答案 3 :(得分:3)
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;
}
答案 4 :(得分:2)
您必须区分static
或auto
变量的初始化和头部的动态分配。对于第一个,执行命名的初始化程序,第二个是一个指定良好的init函数。
所有这一切都很好
packed into macros确实为您提供了一个简单的static/auto
初始化,类似于C ++中的new
。
答案 5 :(得分:1)
如果你正在寻找一个面向对象的“仿真”而不是C,我强烈推荐GObject类型系统[1],它已经成熟并且很大程度上被GTK使用了。
GLib [2]还为小对象提供了一个很好的切片分配器,目前由GNOME使用。