QM  7.0.0
Model-Based Design Tool
Loading...
Searching...
No Matches
Working with Class Operations

Working with AttributesWorking with Free Operations

Operations attached to a class can access individual instances of the class, except for a static class operation, which cannot access any particular instance.

Class Operations in C

In C, a non-static class operation corresponds to a function that (by a coding convention) takes the me-pointer to the struct with class attribute. The me-pointer is generated automatically by QM and should NOT be provided explicitly.

Example of a class operation in C

For example, operation eval in class Calc shown in the screen shot above will be generated as:
bool Calc_eval(Calc const * const me, double op, uint8_t oper)

Note
The me pointer parameter is of type Calc const *... because the specifier const is provided. Such const operation promises not to change the class instance.

Class Constructors in C

In C, a constructor is just like any other class operation in that QM will generate the me-pointer as the first parameter. By convention, a constructor should be named ctor, or ctor1, ctor2, etc. if you have more constructors with different signatures (different parameters). The ctor function should have return type void. It can have any number of parameters.

Class constructor in C

This piece of the model generates the following code:

void Philo_ctor(Philo * const me) {
QActive_ctor(&me->super, Q_STATE_CAST(&Philo_initial));
QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
}
Note
The C constructor must always call the superclass' as well as members' constructors explicitly. For example, the Philo_ctor() in the listing above calls the superclass' constructor QActive_ctor() as well as member constructor QTimeEvt_ctorX().

Invoking Constructors in C

In C, all constructors must be called explicitly. This often poses a problem with encapsulation. For example, you might not want to expose the whole Active Object class declaration (to get to the constructor). In these cases, the example models in QP/C use an idiom, in which the special free operation <Class>_ctor_caller() (or just <Class>_ctor()) is provided just to call the constructor on an implicit instance.

For example, the model in the screen shot above contains the free operation Philo_ctor_call(), which is defined as follows

void Philo_ctor_call(void) {
for (uint8_t n = 0U; n < N_PHILO; ++n) {
Philo_ctor(&Philo_inst[n]); /* <== ctor */
}
}

This particular "ctor call" invokes constructors of all Philo instances in the system. Later, in the main() function, only the free Philo_ctor_call() operation is called, without exposing the declaration of the Philo class (and its constructor):

void main(void) {
. . .
/* start the active objects... */
Philo_ctor_call(); /* <== call all Philosopher ctors */
for (n = 0U; n < N_PHILO; ++n) {
QActive_start(AO_Philo[n], /* AO to start */
. . .
}
. . .
}

Class Destructors in C

In C, a destructor should be named xtor. The xtor class operation should have return type void and should not take any parameters (except of the implicit me pointer).

Class Operations in C++

In C++, a non-static class operation corresponds to a class member function, that is a function with the this-calling convention.

Example of a class operation in C++

For example, operation eval in class Calc shown in the screen shot above will be generated as:
bool Calc::eval(double op, std::uint8_t oper)

Class Constructors in C++

In C++, a constructor has the same name as the class and no return value. A constructor can have any number of parameters and a class may have any number of overloaded constructors. Constructors may have any accessibility: public, protected or private.

C++ Constructor Initializer List

To provide the constructor initializer list, you put the list in the code panel starting with the colon (':') optionally preceded by any number of spaces. You can continue the list for as many lines as you wish.

The constructor initializer list might be followed by the body of the constructor. To start the body, you simply leave one (or more) empty lines after the initializer. QM will interpret all lines of code after such an empty line as the body of the constructor.

Finally, you might skip the constructor initializer list altogether by simply not placing the colon (':') at the beginning.

The following screen shot shows a C++ constructor with a constructor initializer list and a body.

Class constructor in C++

This piece of the model generates the following code:

Table::Table() noexcept
: QActive(&initial)
{
for (uint8_t n = 0U; n < N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}
}

Explicit Constructor in C++

You can make a C++ constructor explicit by providing the keyword explicit in the return type filed in the Property Sheet. An example of an explicit constructor is provided in the Table constructor shown in the screen shot above.

Class Destructors in C++

In C++, a destructor should be named ~<Class>. The destructor class operation should have no return type and should not take any parameters (except of the implicit this-pointer).

Static (Class-Wide) Operations

Static class operation does not have access to any specific instance of a class, but has permissions to access any attributes of any instance of the class. In C, a static class operation does not take the me-pointer. Similarly, in C++, a static class operation does not take the implicit this-pointer. You make a given class operation static by checking the static checkbox in the Class Operation Property Sheet.

Class Operation Property Sheet

Class operation Property Sheet

The class operation property sheet allows you to set the following properties:

  • operation name
  • operation return type drop-down box (NOTE: accepts also user-supplied types)
  • operation specifier allows you to provide such specifiers as: const (for C/C++),
    and override, noexcept, =delete, =0 (for C++ only)
  • operation virtual checkbox (supported for C++ only)
  • operation inline checkbox
  • operation documentation for documenting the operation (see also generate comments)
  • operation code/pseudocode for specifying code of the operation (NOTE: currently not used)

Working with AttributesWorking with Free Operations