对于使用结构定义的C用户类型,是否有某种方法可以使用某种默认构造函数(如C++版本)?
我已经有一个像快速初始化程序(就像那个一样)的宏,pthread_mutex
但我想知道你是否可以在声明中填充结构的某些(或所有)字段.
例如,通过这个pthread_mutex
例子,我想
pthread_mutex_t my_mutex;
具有相同的效果
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
Tim.. 38
您可以创建带有指向结构的指针的初始化函数.这是常见的做法.
也是创建结构并初始化它的函数(如工厂) - 所以从来没有时间结构在"客户端"代码中"未初始化".当然 - 假设人们遵循惯例并使用"构造函数"/工厂......
可怕的伪代码,没有错误检查malloc或免费
somestruct* somestruct_factory(/* per haps some initializer agrs? */) { malloc some stuff fill in some stuff return pointer to malloced stuff } void somestruct_destructor(somestruct*) { do cleanup stuff and also free pointer free(somestruct); }
有人可能会出现并解释一些早期C++预处理器/编译器如何在C中完成所有这些工作.
您可以创建带有指向结构的指针的初始化函数.这是常见的做法.
也是创建结构并初始化它的函数(如工厂) - 所以从来没有时间结构在"客户端"代码中"未初始化".当然 - 假设人们遵循惯例并使用"构造函数"/工厂......
可怕的伪代码,没有错误检查malloc或免费
somestruct* somestruct_factory(/* per haps some initializer agrs? */) { malloc some stuff fill in some stuff return pointer to malloced stuff } void somestruct_destructor(somestruct*) { do cleanup stuff and also free pointer free(somestruct); }
有人可能会出现并解释一些早期C++预处理器/编译器如何在C中完成所有这些工作.
在这种情况下,C++与C不同,它没有"类".但是,C(与许多其他语言一样)仍然可以用于面向对象的编程.在这种情况下,构造函数可以是初始化结构的函数.这与构造函数相同(只有不同的语法).另一个区别是你必须使用malloc()(或某些变体)分配对象.在C++中,您可以使用'new'运算符.
例如C++代码:
class A { public: A() { a = 0; } int a; }; int main() { A b; A *c = new A; return 0; }
等效C代码:
struct A { int a; }; void init_A_types(struct A* t) { t->a = 0; } int main() { struct A b; struct A *c = malloc(sizeof(struct A)); init_A_types(&b); init_A_types(c); return 0; }
函数'init_A_types'在C++中作为构造函数运行.
让我们来谈谈在过去被认为是最佳实践的完整工程解决方案.
结构的问题是一切都是公共的,所以没有数据隐藏.
我们可以解决这个问题
您创建两个头文件.一个是代码客户端使用的"公共"头文件.它包含这样的定义:
typedef struct t_ProcessStruct *t_ProcessHandle; extern t_ProcessHandle NewProcess(); extern void DisposeProcess(t_ProcessHandle handle); typedef struct t_PermissionsStruct *t_PermissionsHandle; extern t_PermissionsHandle NewPermissions(); extern void DisposePermissions(t_PermissionsHandle handle); extern void SetProcessPermissions(t_ProcessHandle proc, t_PermissionsHandle perm);
然后你创建一个私有头文件,其中包含如下定义:
typedef void (*fDisposeFunction)(void *memoryBlock); typedef struct { fDisposeFunction _dispose; } t_DisposableStruct; typedef struct { t_DisposableStruct_disposer; /* must be first */ PID _pid; /* etc */ } t_ProcessStruct; typedef struct { t_DisposableStruct_disposer; /* must be first */ PERM_FLAGS _flags; /* etc */ } t_PermissionsStruct;
然后在您的实现中,您可以执行以下操作:
static void DisposeMallocBlock(void *process) { if (process) free(process); } static void *NewMallocedDisposer(size_t size) { assert(size > sizeof(t_DisposableStruct); t_DisposableStruct *disp = (t_DisposableStruct *)malloc(size); if (disp) { disp->_dispose = DisposeMallocBlock; } return disp; } static void DisposeUsingDisposer(t_DisposableStruct *ds) { assert(ds); ds->_dispose(ds); } t_ProcessHandle NewProcess() { t_ProcessHandle proc = (t_ProcessHandle)NewMallocedDisposer(sizeof(t_ProcessStruct)); if (proc) { proc->PID = NextPID(); /* etc */ } return proc; } void DisposeProcess(t_ProcessHandle proc) { DisposeUsingDisposer(&(proc->_disposer)); }
会发生什么是您在公共头文件中为结构做出前向声明.现在你的结构是不透明的,这意味着客户不能与它们混在一起.然后,在完整声明中,在每个结构的开头都包含一个析构函数,您可以调用它.您可以为每个人使用相同的malloc分配器具有相同的dispose功能.您为要公开的元素创建公共set/get函数.
突然间,你的代码更加清晰.您只能从分配器或调用分配器的函数获取结构,这意味着您可以瓶颈初始化.您构建析构函数以便可以销毁对象.你去吧.顺便说一下,比t_DisposableStruct更好的名字可能是t_vTableStruct,因为它就是这样.您现在可以通过使用vTableStruct来构建虚拟继承,该vTableStruct是所有函数指针.你也可以用纯粹的oo语言(通常)做一些你不能做的事情,比如在运行中更改vtable的select元素.
最重要的一点是,有是用于制造结构安全和initializable工程模式.
不,不是直接的.您最接近的方法是编写一个分配实例的函数并填充一些字段.