对象初始化方法

初始化函数会初始化实例的特性和链接。初始化方法会假定之前已为对象分配了内存(不论静态或动态)。对象初始化方法的名称格式为 <object>_Init()

例如,以下示例是为对象 A 所生成的初始化方法的原型:

void A_Init(struct A_t* const me);

第一个自变量是指向要初始化的对象的常量指针。const 关键字以 ANSI C 定义了常量指针。将常量指针作为自变量来传递使操作能够更改指针所处理的对象的值,而不是自变量 me 所包含的地址。

对象初始化方法具有以下职责,它按以下顺序依次执行它们:

  1. 调用子对象初始化方法函数(如果对象具有子对象)。
  2. 为关联关系设置设置链接。
  3. 执行为构造函数的主体输入的用户代码。该代码必须包含对象数据的初始化。
  4. 初始化聚集的框架对象(例如,RiCTaskRiCReactiveRiCMonitor 对象)。

子对象初始化包含为组合对象的每个子对象调用初始化方法。就数组而言,每个子对象的初始化都可以包含 $index 关键字。

缺省情况下,初始化方法没有自变量(不同于 me 自变量)。如果您创建带有自变量的初始化方法,可以在“对象”窗口中为自变量输入初始值。IBM® Rational® Rhapsody® 从“对象”窗口中输入的值为带有自变量的初始化方法生成初始化代码。

初始化子对象

组合使用父代的初始化方法中对 initRelations() 的调用进行初始化。例如,为具有子对象 E 的对象 D 生成以下初始化方法:

void D_Init(D* const me) {
   initRelations(me);
}

D 的初始化方法中的 initRelations() 调用会调用 E 的初始化方法:

static void initRelations(D* const me) {
    E_Init(&me->E);
}

如果子对象是作为数组来实施的(例如,由于子对象具有大于 1 的数字多重性),则这些子对象使用 initRelations() 操作中的 while() 循环来进行初始化。例如,如果 E 的多重性为 2,E 实施为 D 内的两个元素数组。以下示例的 while() 循环生成在 DinitRelations() 操作中,以初始化 E 的两个实例:

static void initRelations(D* const me) {
   E_Init(&(me->E));
   {
      RhpInteger iter = 0;
      while (iter < 5){
         E_Init(&((me->itsE)[iter]));
         iter++;
      }
   }
}

设置链接

如果相关对象不是组合对象的组件,您可以使主程序将其中一个对象进行实例化,即将其选择为初始实例(在配置的“初始化”选项卡中)。在对象的该初始化方法中,您可以显式地创建相关对象,然后设置指向它的链接。例如,如果对象 A 和对象 B 相关,并且 main() 函数将 A 实例化为初始实例,那么在 A 的初始化方法的主体中,您可以写入以下代码以将其链接设置为指向 B

B *itsB = B_Create();
A_setItsB(me, itsB);

将链接设置为对多关系包含了调用容器的初始化方法。在以下代码中,对 RiCCollection_Init() 的调用设置了 Furnace 的链接指向三个 itsRooms。将 RiCTRUE 值传递到 RiCCollection_setFixedSize() 表示集合为固定大小:

void Furnace_Init(Furnace* const me, RiCTask * p_task) {
    RiCReactive_init(&me->ric_reactive, (void*)me, 
        p_task, &Furnace_reactiveVtbl);
    RiCCollection_Init(&me->itsRoom, 3);
    NOTIFY_REACTIVE_CONSTRUCTOR(me, NULL, Furnace,
        Furnace, Furnace(), 0, Furnace_SERIALIZE);
    {
        RiCCollection_setFixedSize(&me->itsRoom,
            RiCTRUE);
    }
    initStatechart(me);
    NOTIFY_END_CONSTRUCTOR(me);
}

NOTIFY_CONSTRUCTOR()NOTIFY_END_CONSTRUCTOR() 调用是在启用动画时生成的检测宏。第一个宏在初始化方法被调用时通知动画程序,并创建动画实例。第二个宏在初始化程序即将退出时通知动画程序。

执行用户初始化代码

为构造函数输入的用户代码包含对象特性的初始化。您可以为对象构造函数中的每个参数指定实际值。实际值是作为未解释文本按字面插入的。

用户代码生成在代码中的 /*#[/*#] 符号之间。例如,您可以在初始化方法的实施字段中输入以下代码:

RiCString temp;
RiCString_Init(&temp, "Hello World");
A_print(me, temp);

该代码的实施如下所示:

void A_Init(struct A_t* const me) {
    NOTIFY_CONSTRUCTOR(me, NULL, A, A, A(), 0,
        A_SERIALIZE);
    me->itsB = NULL;
    {
        /*#[ operation A() */
        RiCString temp;
        RiCString_Init(&temp, "Hello World");
        A_print(me, temp);
        /*#]*/
    }
    NOTIFY_END_CONSTRUCTOR(me);
}

反馈