如何在C中模拟构造函数和析构函数行为(对于特定数据类型)

Hom*_*lli 7 c c++ constructor destructor

我有一个C(嵌套)结构,我想在我的代码中自动初始化和销毁​​.

我正在使用Linux上的GCC(4.4.3)进行编译.我隐约知道GCC函数属性构造函数和析构函数,但它们提供的构造/销毁似乎与整个程序有关(即在调用main()之前等).

我希望能够为不同的数据类型使用不同的init/cleanup函数 - 这个C++就像我可以使用POC模拟的行为吗?

我已经包含了C++标记,因为这实际上是我试图在C中模拟的C++行为.

Pau*_*nta 10

没有办法自动执行此操作,至少不能以任何便携方式执行此操作.在C中,您通常具有的功能有点像构造函数和析构函数 - 它们(de)分配内存和(de)初始化字段 - 除非必须显式调用它们:

typedef struct{} MyStruct;
MyStruct *MyStruct_New(void);
void MyStruct_Free(MyStruct *obj);
Run Code Online (Sandbox Code Playgroud)

这种语言根本就不是为此设计的,你不应该试图强迫它,imo.如果你想自动销毁,你不应该使用C.

  • 好吧,曾经可以(也可能应该)添加"de-/initialize only"函数(`void MyStruct_Init(MyStruct*); void MyStruct_Finalize(MyStruct*);`)来处理堆栈或使用预先分配的内存(`. ..New/... Free`然后变成`MyStruct*p = malloc(sizeof(*p)); MyStruct_Init(p); return p;`和`MyStruct_Finalize(p); free(p);`).但一般来说,是的. (3认同)

Fil*_*efp 6

#define你的方式解决问题...

正如之前的作者所指出的那样,没有自动的方式来做你所要求的事情,遗憾的是,由于C没有任何方法可以做出真正的OOP.

但是程序员总是可以通过任何障碍来破坏他自己.在这篇文章的最后,我给你写了一个样本黑客来规避这个问题.

有一些方法可以清理所提供的宏,但它不会那么便携.



- C99实施

#include <stdio.h>
#include <stdlib.h>
Run Code Online (Sandbox Code Playgroud)

...

#define SCOPIFY(TYPE,NAME, ...) { \
  ctor_ ## TYPE(& NAME); \
  __VA_ARGS__ \
  dtor_ ## TYPE(& NAME); \
} (void)0
Run Code Online (Sandbox Code Playgroud)

...

typedef struct {
  int * p;
} Obj;

void
ctor_Obj (Obj* this) {
   this->p = malloc (sizeof (int));
  *this->p = 123;

  fprintf (stderr, "Obj::ctor, (this -> %p)\n", (void*)this);
}

void
dtor_Obj (Obj* this) {
  free (this->p);

  fprintf (stderr, "Obj::dtor, (this -> %p)\n", (void*)this);
}
Run Code Online (Sandbox Code Playgroud)

...

int
main (int argc, char *argv[])
{
  Obj o1, o2;

  SCOPIFY (Obj, o1, 
    fprintf (stderr, "  o1.p -> %d\n", *o1.p);

    SCOPIFY (Obj, o2, 
      int a, b;

      fprintf (stderr, "  o2.p -> %d\n", *o2.p);
      (*o1.p) += (*o2.p);
    );  

    fprintf (stderr, "  o1.p -> %d\n", *o1.p);
  );  

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出(http://ideone.com/WYrjU)

Obj::ctor, (this -> 0xbf8f05ac)
  o1.p -> 123
Obj::ctor, (this -> 0xbf8f05a8)
  o2.p -> 123
Obj::dtor, (this -> 0xbf8f05a8)
  o1.p -> 246
Obj::dtor, (this -> 0xbf8f05ac)
Run Code Online (Sandbox Code Playgroud)

  • @PaulManta 是的,老实说,我主要是在闲逛..但由于 C 不是一种旨在处理 OOP 的语言,因为 OP 要求没有太多工作要做。 (2认同)