代码之家  ›  专栏  ›  技术社区  ›  Hernán Eche Shankar ARUL

防止在初始化之前使用函数,如C中的构造函数

  •  3
  • Hernán Eche Shankar ARUL  · 技术社区  · 15 年前

    这是我预防Funa、Funb、Func等的方法。用于在初始化之前使用

    #define INIT_KEY 0xC0DE //any number except 0, is ok
    
    static int initialized=0;
    
    int Init()
    {
      //many init task
      initialized=INIT_KEY;
    }
    
    
    int funA()
    {
     if (initialized!=INIT_KEY) return 1;
     //..
    }
    
    int funB()
    {
     if (initialized!=INIT_KEY) return 1;
     //..
    }
    
    int funC()
    {
     if (initialized!=INIT_KEY) return 1;
     //..
    }
    

    这种方法的问题在于,如果在一个循环中调用其中的一些函数 所以“如果(初始化!=init_key)“被一次又一次调用,尽管这不是必需的。

    这是一个很好的例子,说明了为什么构造函数是有用的,哈哈,如果它是一个对象,我可以肯定,当它被创建时,会调用初始化,但是在C语言中,我不知道如何进行初始化。

    欢迎有其他想法!

    5 回复  |  直到 14 年前
        1
  •  5
  •   EvilTeach    15 年前

    使用指向函数的指针。

    在构造时,将函数指向函数 它执行所需的初始化,然后更新函数指针以指向执行该工作的实际函数。

    我在一个类中使用了指向成员函数的指针数组。类有一个内部整数,表示对象的状态。整数用于下标到指向成员函数的指针数组…状态0执行初始化。状态1,完成工作,状态2将事情设置回状态1。

    它工作得很干净。

        2
  •  4
  •   el.pescado - нет войне    15 年前

    您可以使用一些使用预处理器宏的断言:

    #ifdef DEBUG
    #  define ENSURE_INITIALIZED(obj) \
         do { \
             if (obj->initialized != INIT_CODE) { \
                 fprintf (stderr, "Object %p not initliaized (%s:%d)\n", obj, __FILE__, __LINE__); \
                 abort (); \
             } \
         } while (0)
    #else
    #  define ENSURE_INITIALIZED(obj)
    #endif
    
    voif foo (Object *obj) {
        ENSURE_INITIALIZED (obj);
    }
    

    这将检查初始化代码,但仅在调试内部版本中-在生产内部版本中,它的计算结果将为no-op。

    打电话 abort 将异常终止程序,通常会留下核心转储,或者在调试器中运行时中断程序。

        3
  •  1
  •   Ioan    15 年前

    将函数放入结构中(使用函数指针访问它们)。提供一个“构造”函数来创建该结构并在结构中分配正确的函数地址。几乎和Evilteach的想法一样。

        4
  •  1
  •   ShinTakezou    15 年前

    你可以想想 不同的 解决。在循环中,无论选择什么解决方案,都将始终执行一些额外的代码(最好是在后台执行),以防止执行函数。您可以在循环中跳过funx的执行,但检查funx是否可以执行并放置在不同的位置将是额外的代码。

    由于通常在其他任务之前完成初始化,这是一个奇怪的问题,或者是命名错误(您不应该称之为初始化)。

    如果需要,函数可以自己调用初始值设定项,比如

    if (!initialized) initialize();
    

    总是额外的代码,还有!从那时起,initialized将始终为false。

    但避免反复检查的方法是在游戏开始真正玩之前,在正确的位置显式调用初始化。(否则不要调用它初始化)。

    如果它是一个物体,…你不需要这个东西。要“trig”一个构造函数,必须创建对象(至少在许多OO语言中),例如, new MyClass() 或者“声明它”;这里对“new”的调用(这不是一个调用,但是我们可以这样认为)或者“declaration”被更改为对显式初始值设定项的调用。你看起来很简单

    Object a;
    // ...
    a.method(); //or
    
    Object *a = new Object();
    // ...
    a->method();
    

    将是

    init()
    // ...
    funA();
    

    即使这个例子不“符合”您的“需要”,它应该清楚地表明显式初始值设定项并没有那么糟糕,并且OO语言确实没有必要“修复”这个问题。

    您可以控制何时可以调用这些函数,因此根本不需要检查;在许多库中,它首先需要调用特殊的in it函数,然后才能使用它们,或者必须预料到“奇怪”行为。

        5
  •  1
  •   INS    15 年前

    解决方案是这样进行初始化(在每个文件中):

    static int initResult = Init();
    

    当程序启动时,这些静态变量将自动初始化并调用函数。

    重要注意事项: 如果需要在多个文件中进行此类初始化(通常对象的链接顺序指示初始化顺序),则初始化顺序未定义,但 没有规则 为此)。所以你做这个的时候一定要小心。