Working with typedefs

In C++, typedefs are intensively used to introduce compiler-controlled simple types used as short names for complex types. Modelio C++ Designer lets you easily create typedefs of arbitrary complex types.

To create a C++ typedef, you simply create a UML datatype with the intended typedef name in the model. To specify the represented C++ type, the datatype is decorated by the “Cxx.TypeExpr” tagged value, and the C++ type expression is provided in the in the first tagged value parameter.

Because C++ permits very complex recursive type definitions, you can put the “$name” ACT macro in the type expression to specify exactly where the typedef name should be injected. If the “$name” macro is not specified, it is automatically added at the end of the type expression.

Modelio C++ Designer translates the UML datatype into the C++ typedef declaration by adding the “typedef” keyword and substituting the “$name” macro by the typedef name. The datatypes defined in a class are generated in the class definition, while the datatypes defined in a package are generated in the package namespace in the package header file.

For example, we want to define the task handlers in the “Task” class. Task handlers are specific functions that run when certain conditions in the task are satisfied, for example, when the task is completed or delayed. A task handler is represented by the pointer to a function, which takes the “Task” instance as a parameter and returns a Boolean status.

To represent the task handlers, we introduce the “TaskHandler” typedef in the “Task” class, which expresses this pointer to a handler function. We then create the “TaskHandler” datatype in the “Task” class and decorate this datatype by the “Cxx.TypeExpr” tagged value with the following expression:

1bool (*$name)(Task* theTask)

The next figure illustrates these operations:


The result of the operations you have just carried out

We are now going to continue by defining the newly-created datatype as having public visibility. Modelio C++ Designer produces the following code for the “Task” class.

 1//includes for used library types
 2#include <string>
 3#include <set>
 4#include <list>
 5
 6//automatic includes (friends, associated classes, etc)
 7#include "MyPlanner/TaskManagement/SimpleProject.h"
 8#include "MyPlanner/TaskManagement/HumanResource.h"
 9
10namespace MyPlanner
11{
12    namespace TaskManagement
13    {
14        class Task
15        {
16        //typedefs
17
18        public:
19            typedef bool (*TaskHandler)(Task* theTask);
20
21        //attributes
22
23        public:
24            std::string name;
25            std::string wbsCode;
26
27        //associations
28
29        protected:
30            SimpleProject* project;
31            std::set<Task> subTasks;
32            Task* owner;
33            std::list<HumanResource> resource;
34
35        //operations
36
37        public:
38            Task();
39            Task(const Task& value);
40            Task& operator =(const Task& value);
41            ~Task();
42            bool addSubTask(int wbsNum, Task& SubTask);
43            std::string getName();
44            void setName(std::string value);
45            std::string getWbsCode();
46            SimpleProject* getProject();
47            std::list<HumanResource>& getResource();
48            std::set<Task>& getSubTasks();
49            Task* getOwner();
50            void setOwner(Task* value);
51
52        //non-modeled members
53
54        };   
55    }
56}

After this, we can easily create attributes of “TaskHandler” type. For example, let’s create the “handlers” attribute that models the mapping of handlers assigned to the given events for the task, and then create its model- level accessor. With the help of the accessor, we can assign our handlers to given events for a given task, and our code is concise due to the use of typedef.


The “handlers” attribute and the “getHandlers” accessor

Modelio C++ Designer produces the following code for the “getHandlers” accessor definition, where the typedef defined in the “Task” class is correctly referred to.

 1//class header file
 2#include "MyPlanner/TaskManagement/Task.h"
 3
 4namespace MyPlanner
 5{
 6    namespace TaskManagement
 7    {
 8        //...
 9        std::hash_map<std::string,Task::TaskHandler>& Task::getHandlers()
10        {
11            //modifiable zone @16423@30671900:2486@T
12            return handlers;
13            //modifiable zone @16423@30671900:2486@E
14        }
15    }
16}