C中的默认构造函数 P>有没有一种方法来构造一个默认的构造函数(例如C++),用结构定义的C用户类型?< /P>

C中的默认构造函数 P>有没有一种方法来构造一个默认的构造函数(例如C++),用结构定义的C用户类型?< /P>,c,constructor,C,Constructor,我已经有了一个类似于快速初始值设定项的宏(类似于pthread\u mutex),但我想知道您是否可以在声明时填充结构的一些(或全部)字段 例如,对于pthread\u mutex示例,我希望 pthread_mutex_t my_mutex; 与 pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER; 不,不是直接的。最接近的方法是编写一个分配实例并填充某些字段的函数。您可以编写一个返回C结构的函数: struct file create

我已经有了一个类似于快速初始值设定项的宏(类似于
pthread\u mutex
),但我想知道您是否可以在声明时填充结构的一些(或全部)字段

例如,对于
pthread\u mutex
示例,我希望

pthread_mutex_t my_mutex;

pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;

不,不是直接的。最接近的方法是编写一个分配实例并填充某些字段的函数。

您可以编写一个返回C结构的函数:

struct file create_file(int i, float f) {
    struct file obj = { i, f };
    // other code here...
    return obj;
}
如果你想知道在C中是否可以有“正常”的成员函数,那么,在某种程度上,你可以。我更喜欢对象作为第一个参数样式。将指向结构的指针作为第一个参数传递。通过这种方式,您可以使用多个函数来定义对象的接口:

int file_get_integer(struct file *self) { return self->i; }
float file_get_float(struct file *self) { return self->f; }
如果您以这种风格编写,那么您最后得到的是一种抽象数据类型。我见过通过在函数结构中有函数指针然后在执行:

的方法来模拟C++中使用的成员函数调用语法的家伙。
obj.get_integer(&obj);

linux内核使用它来定义文件系统驱动程序的接口。这是一种写作风格,一个人可能喜欢,也可能不喜欢。我不太喜欢它,因为我一直在为数据使用结构成员,而不是像流行的面向对象语言那样模拟成员函数调用。

您可以创建带结构指针的初始值设定项函数。这是惯例

还包括创建结构并对其进行初始化(如工厂)的函数,因此在“客户机”代码中从来没有结构“未初始化”的时候。当然-这假设人们遵循惯例并使用“构造函数”/“工厂”

可怕的伪代码,在malloc或free上没有错误检查

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.中执行这一切的,

< P>不,结构只是一堆数据。无法在结构中声明函数,因此无法为其创建构造函数。

不太可能。如果我没记错的话,最接近类的是结构。分配内存并填充字段。我不知道你会怎么做一个通用的构造函数类型的东西。理论上,您可以编写一个宏来完成其中的一些操作。不过,不确定这是否真的值得。

假设您想在C中实现这一点,那么您的问题不是关于C++中的结构:

我通常做的是创建一个函数init_,不管什么,它接受指向结构(或其他变量)的指针,并将其设置为我想要的值

如果它是一个全局变量(初始化为零),您可以通过在其中设置一个“initialized”标志来模拟一个无参数构造函数,然后让您的其他函数检查该标志,如果该标志为零,则初始化该结构。不过,我一点也不确定这是个好主意


和其他人一样,你也可以用宏来做一些可怕的事情……

基本上,C++创建了包含方法地址的指针列表。此列表称为类定义(类定义中还有一些数据,但我们暂时忽略了这些数据)

纯C中有“类”的常见模式是定义“结构类”。结构的一个字段是工厂函数,它返回类的“实例”。我建议使用宏来隐藏强制转换:

typedef struct __class * class;
typedef void (*ctor_ptr)(class);
struct class {
    char * name;
    ctor_ptr ctor;
    ... destructor and other stuff ...
}

#define NEW(clz) ((struct something *)(((struct class *)clz)->ctor(clz)))
现在,您可以通过为每个类创建“struct class”类型的结构来定义所拥有的类,然后调用其中存储的构造函数。这同样适用于析构函数等

如果需要实例的方法,则必须将它们放入类结构中,并在实例结构中保留指向类的指针:

#define NEW_SOMETHING() ((struct something *)NEW(&something_definition))
#define METHOD(inst, arg) ((struct something_class *)(((struct something *)inst)->clz)->method(inst, arg))
NEW\u SOMETHING
将使用存储在结构
SOMETHING\u definition
中的类定义创建“SOMETHING”的新实例。方法将在此实例上调用“方法”。注意,对于真正的代码,您需要检查
inst
是否实际上是
某物的实例(比较类指针,类似的)

继承有点棘手,留给读者作为练习

<>请注意,在C++中,你可以做C++中的所有事情。C++编译器并没有神奇地用其他东西取代你的CPU。这需要更多的代码来完成


如果您想看一个示例,请查看(Gtk+项目的一部分)。

在本例中,C++与C的不同之处在于它没有“类”。然而,C(和许多其他语言一样)仍然可以用于面向对象编程。在这种情况下,构造函数可以是初始化结构的函数。这与构造函数相同(只是语法不同)。另一个区别是,您必须使用malloc()(或某种变体)分配对象。在C++中,你将使用新的操作符。 <> > 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;
}

函数'iNITAYAYTYPE '作为构造函数将在C++中.

您可能想看C++编译器。与试图用库和宏将构造函数等连接到C上相比,它以一种更优雅、更标准的方式为您提供了更多面向对象的特性,这在一种具有类似C的语法的语言中是无法记住的

如果这对你不起作用,那么看看GObject。它是GTK和Gnome中使用的C对象系统,几乎可以将“C中的对象”拖动到11

来自维基百科:

GLib对象系统或GObject是一个自由软件库(由LGPL覆盖),它提供了一个可移植的对象系统和透明的跨语言互操作性。 系统支持构造函数、析构函数、单一继承、接口、虚拟公共和私有方法以及
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));
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define new(TYPE, ...) memdup(&(TYPE){ __VA_ARGS__ }, sizeof(TYPE))

void * memdup(const void * obj, size_t size)
{
    void * copy = malloc(size);
    return copy ? memcpy(copy, obj, size) : NULL;
}

struct point
{
    int x;
    int y;
};

int main()
{
    int * i = new(int, 1);
    struct point * p = new(struct point, 2, 3);

    printf("%i %i %i", *i, p->x, p->y);

    return 0;
}
struct some_struct {
    int a;
    float b;
};
#define some_struct_DEFAULT { 0, 0.0f}
struct some_struct *some_struct_create(void) {
    struct some_struct *ptr = malloc(sizeof some_struct);
    if(!ptr)
        return ptr;

    *ptr = some_struct_DEFAULT;
    return ptr;
}
// (...)
struct some_struct on_stack = some_struct_DEFAULT;
struct some_struct *on_heap = some_struct_create();
#include        <stdio.h> 

void __attribute__ ((constructor)) default_constructor() 
{ 
    printf("%s\n", __FUNCTION__); 
} 

int main() 
{ 
    printf("%s\n",__FUNCTION__);
    return 0; 
}
#include    <stdio.h> 
#include    <stdlib.h>

struct somestruct
{
    int     empid;
    char *  name;
};

struct somestruct * str1;

void __attribute__ ((constructor)) a_constructor() 
{ 
    str1 = (struct somestruct *) malloc (sizeof(struct somestruct));
    str1 -> empid = 30228;
    str1 -> name = "Nandan";
} 

void __attribute__ ((destructor)) a_destructor()
{
    free(str1);
}

int main() 
{ 
    printf("ID = %d\nName = %s\n", str1 -> empid, str1 -> name);
    return 0;
}