如何在C中实现单例对象?

问题描述 投票:0回答:1

我需要

OBJECT
可供其他对象使用。要求是
OBJECT
不需要通过任何外部调用进行初始化。所以我从这样开始......

//  .h
struct My_Shared_Obj {
  bool is_happy;
  struct foo *foos;
};

typedef struct My_Shared_Obj *mysharedobj;

//  .c
static mysharedobj MSO = NULL;

mysharedobj __instance();
void __mso_do_something();

void __mso_do_something() {
  mysharedobj _mso = __instance();

  // now do something with struct members
}

mysharedobj *__instance() {
  if(MSO == NULL) {
    // initialize MSO
  }

  return MSO;
}


// we have an 'API' as follows
const struct MSO_API API = {
  .do_something = &__mso_do_something
};
  1. 这是实现“自初始化”对象的最佳方法吗? 参考行为似乎并未对
  2. MSO
  3. 进行更改,而仅针对函数的范围进行更改
    
    
  4. 此外,同一源代码中的某些功能只能通过 API 访问......例如:

static struct My_Shared_Obj *MSO = NULL; /* This method makes an assumption that since it can ever only be called by an API function that the __instance() function has been invoked and that MSO will be a valid object. */ void __foo_add(foo *ptr) { // assume we have next incrementing somewhere MSO->foos[next] = *ptr; } void __mso_do_something() { struct My_Shared_Obj _mso = __instance(); // hypothetical condition; assume we have a function that provides a foo for us... if (!_mso->is_happy) { __foo_add(get_a_foo()); _mso->is_happy = true; } }

我很难正确引用 
MSO

对象。上面的例子并不是故意的。这就是我所尝试过的(

已更改名称以保护无辜者
)。我已经尝试了一段时间,但没有得到我需要的结果。

c singleton pass-by-reference
1个回答
0
投票
我需要一个对象被其他对象使用。要求是对象不需要通过任何外部调用进行初始化。

如果所有成员的初始值都可以写成常量表达式

...然后只需使用初始化器声明对象本身:

static struct My_Shared_Obj the_object = { .is_happy = 1, .foos = NULL };

初始化就像在程序开始运行之前一样发生,因此没有函数可以看到未初始化的值。

在同一个翻译单元内,可以直接访问对象。 如果您想将其公开在 TU 之外,那么还提供一个外部函数来执行此操作:

struct My_Shared_Obj *get_mso(void) { return &the_object; }

如果任何初始值需要运行时计算

...那么您需要通过一个函数来控制对该对象的所有访问,该函数首先测试是否对其进行初始化。 在这种情况下,使结构本身成为该函数的静态局部变量是有意义的,并且您可以提供另一个指定是否初始化的变量:

struct My_Shared_Obj *get_mso(void) { static struct My_Shared_Obj the_object; static _Bool is_initialized; if (!is_initialized) { // ... initialize the_object ... is_initialized = 1; } return &the_object; }

在函数内部定义共享对象不会给它任何链接,因此即使同一 TU 中的其他函数也无法访问它,除非最终通过 
get_mso()

获取指向它的指针。

    

© www.soinside.com 2019 - 2024. All rights reserved.