当前位置:  开发笔记 > 运维 > 正文

C中的默认构造函数

如何解决《C中的默认构造函数》经验,为你挑选了4个好方法。

对于使用结构定义的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中完成所有这些工作.



1> Tim..:

您可以创建带有指向结构的指针的初始化函数.这是常见的做法.

也是创建结构并初始化它的函数(如工厂) - 所以从来没有时间结构在"客户端"代码中"未初始化".当然 - 假设人们遵循惯例并使用"构造函数"/工厂......

可怕的伪代码,没有错误检查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中完成所有这些工作.


......就像一个可怕的灼热的皮疹.
哦,cfront,我们多么想念你.

2> Reed..:

在这种情况下,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++中作为构造函数运行.



3> plinth..:

让我们来谈谈在过去被认为是最佳实践的完整工程解决方案.

结构的问题是一切都是公共的,所以没有数据隐藏.

我们可以解决这个问题

您创建两个头文件.一个是代码客户端使用的"公共"头文件.它包含这样的定义:

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工程模式.



4> ConcernedOfT..:

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

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有