References
Objects are managed using Reference components.
References offer a smart pointer mechanism which guarantees that any MARTe Object can be safely shared (thread and interrupt safe) among different execution units. A different name can also be assigned to each object instance.

Important
The new and delete operators shall not be used to manage the life cycle of any of the framework objects. The framework offers an object creation mechanism that returns a reference.
Each time a new Reference points at a given object, the Object number of references is incremented. Conversely, when a new reference no longer points at an Object, e.g. because it lost scope, the number of reference is decremented. When the number of references pointing at any given object is equal to zero, the object is destroyed.
The Reference constructor allows to create a new object using the class name.
Reference ref1("AClassName", GlobalObjectsDatabase::Instance()->GetStandardHeap());
Using the templated version, ReferenceT, the class type (or any of its polymorphic interfaces) is also constrained to be compatible with the class name. This is the basic mechanism that allows to verify that classes are compatible with a given implementation (e.g. to verify what references are pointing to objects whose class inherit from GAM).
Reference ref1("AClassName", GlobalObjectsDatabase::Instance()->GetStandardHeap());
Reference<ADerivedClass> ref2 = ref1;
Attention
Always check that a Reference IsValid before using it! There are many reasons why a Reference may not be valid: - It was not initialised; - The reference class type is not compatible with the class name; - When assigning a reference to an existent reference (ref1 = ref2), the classes are not compatible (e.g. because they do not share the same interface);
Examples
This example shows how to instantiate an Object by class name and how to assign a name to the instance.
1/**
2 * @file ReferencesExample1.cpp
3 * @brief Source file for class ReferencesExample1
4 * @date 14/03/2018
5 * @author Andre' Neto
6 *
7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
8 * the Development of Fusion Energy ('Fusion for Energy').
9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
11 * You may not use this work except in compliance with the Licence.
12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
13 *
14 * @warning Unless required by applicable law or agreed to in writing,
15 * software distributed under the Licence is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17 * or implied. See the Licence permissions and limitations under the Licence.
18
19 * @details This source file contains the definition of all the methods for
20 * the class ReferencesExample1 (public, protected, and private). Be aware that some
21 * methods, such as those inline could be defined on the header file, instead.
22 */
23
24#define DLL_API
25
26/*---------------------------------------------------------------------------*/
27/* Standard header includes */
28/*---------------------------------------------------------------------------*/
29
30/*---------------------------------------------------------------------------*/
31/* Project header includes */
32/*---------------------------------------------------------------------------*/
33#include "AdvancedErrorManagement.h"
34#include "ClassRegistryDatabase.h"
35#include "ErrorLoggerExample.h"
36#include "Object.h"
37#include "Reference.h"
38#include "StreamString.h"
39
40/*---------------------------------------------------------------------------*/
41/* Static definitions */
42/*---------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------*/
45/* Method definitions */
46/*---------------------------------------------------------------------------*/
47namespace MARTe2Tutorial {
48/**
49 * @brief A MARTe::Object class will be automatically
50 * registered into the ClassRegistryDatabase.
51 */
52class ControllerEx1: public MARTe::Object {
53public:
54 CLASS_REGISTER_DECLARATION()
55
56 /**
57 * @brief NOOP.
58 */
59ControllerEx1 () {
60 gain = 0u;
61 }
62
63 /**
64 * A property.
65 */
66 MARTe::uint32 gain;
67};
68
69CLASS_REGISTER(ControllerEx1, "")
70}
71
72int main(int argc, char **argv) {
73 using namespace MARTe;
74 SetErrorProcessFunction(&ErrorProcessExampleFunction);
75
76 CCString className = "ControllerEx1";
77 //Automatically generate a new object instance based on the class name and on the correct Heap
78 Reference ref1(className, GlobalObjectsDatabase::Instance()->GetStandardHeap());
79 Reference ref2(className, GlobalObjectsDatabase::Instance()->GetStandardHeap());
80 Reference ref3;
81
82 //ref3 is not initialised and thus should not be valid
83 if (ref1.IsValid() && ref2.IsValid() && !ref3.IsValid()) {
84 ref1->SetName("ControllerInstance1");
85 ref2->SetName("ControllerInstance2");
86 //ref1 and ref2 are referencing two different object instances of the same class
87 Object *referencedObj1 = ref1.operator ->();
88 Object *referencedObj2 = ref2.operator ->();
89
90 if (referencedObj1 != referencedObj2) {
91 REPORT_ERROR_STATIC(ErrorManagement::Information, "As expected ref1 "
92 "and ref2 are NOT pointing at the "
93 "same instance (%s != %s).", ref1->GetName(), ref2->GetName());
94 }
95
96 ref3 = ref1;
97 //ref3 is now valid and should point at the same object as ref1
98 Object *referencedObj3 = ref3.operator ->();
99 if (referencedObj1 == referencedObj3) {
100 REPORT_ERROR_STATIC(ErrorManagement::Information, "As expected ref1 "
101 "and ref3 are pointing at the "
102 "same instance (%s == %s).", ref1->GetName(), ref3->GetName());
103 }
104 }
105 else {
106 REPORT_ERROR_STATIC(ErrorManagement::FatalError, "One of the references is not correct.");
107 }
108
109 return 0;
110}
This example highlights how the number of references change during the life cycle of a program.
1/**
2 * @file ReferencesExample2.cpp
3 * @brief Source file for class ReferencesExample2
4 * @date 14/03/2018
5 * @author Andre' Neto
6 *
7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
8 * the Development of Fusion Energy ('Fusion for Energy').
9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
11 * You may not use this work except in compliance with the Licence.
12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
13 *
14 * @warning Unless required by applicable law or agreed to in writing,
15 * software distributed under the Licence is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17 * or implied. See the Licence permissions and limitations under the Licence.
18
19 * @details This source file contains the definition of all the methods for
20 * the class ReferencesExample2 (public, protected, and private). Be aware that some
21 * methods, such as those inline could be defined on the header file, instead.
22 */
23
24#define DLL_API
25
26/*---------------------------------------------------------------------------*/
27/* Standard header includes */
28/*---------------------------------------------------------------------------*/
29
30/*---------------------------------------------------------------------------*/
31/* Project header includes */
32/*---------------------------------------------------------------------------*/
33#include "AdvancedErrorManagement.h"
34#include "ClassRegistryDatabase.h"
35#include "ErrorLoggerExample.h"
36#include "Object.h"
37#include "Reference.h"
38#include "StreamString.h"
39
40/*---------------------------------------------------------------------------*/
41/* Static definitions */
42/*---------------------------------------------------------------------------*/
43
44/*---------------------------------------------------------------------------*/
45/* Method definitions */
46/*---------------------------------------------------------------------------*/
47namespace MARTe2Tutorial {
48/**
49 * @brief A MARTe::Object class will be automatically registered
50 * into the ClassRegistryDatabase.
51 */
52class ControllerEx1: public MARTe::Object {
53public:
54 CLASS_REGISTER_DECLARATION()
55
56 /**
57 * @brief NOOP.
58 */
59 ControllerEx1() {
60 gain = 0u;
61 }
62
63 virtual ~ControllerEx1() {
64 using namespace MARTe;
65 if (GetName() != NULL) {
66 REPORT_ERROR_STATIC(ErrorManagement::Information, "No more "
67 "references pointing at %s [%s]. The Object will be "
68 "safely deleted.", GetName(), GetClassProperties()->GetName());
69 }
70 }
71
72 /**
73 * A property.
74 */
75 MARTe::uint32 gain;
76};
77
78CLASS_REGISTER(ControllerEx1, "")
79}
80
81void Function (MARTe::Reference ref) {
82 using namespace MARTe;
83 REPORT_ERROR_STATIC(ErrorManagement::Information, "Number of references "
84 "pointing at %s is %d", ref->GetName(), ref.NumberOfReferences());
85
86 CCString className = "ControllerEx1";
87 //Automatically generate a new object instance based on the class name and on the correct Heap
88 Reference ref2(className, GlobalObjectsDatabase::Instance()->GetStandardHeap());
89 ref2->SetName("ControllerInstance2(FunctionMember)");
90 REPORT_ERROR_STATIC(ErrorManagement::Information, "Number of references "
91 "pointing at %s is %d", ref2->GetName(), ref2.NumberOfReferences());
92}
93
94int main(int argc, char **argv) {
95 using namespace MARTe;
96 SetErrorProcessFunction(&ErrorProcessExampleFunction);
97
98 CCString className = "ControllerEx1";
99 //Automatically generate a new object instance based on the class name and on the correct Heap
100 Reference ref1(className, GlobalObjectsDatabase::Instance()->GetStandardHeap());
101 ref1->SetName("ControllerInstance1");
102 REPORT_ERROR_STATIC(ErrorManagement::Information, "Number of references "
103 "pointing at %s is %d", ref1->GetName(), ref1.NumberOfReferences());
104 Reference ref2 = ref1;
105 Reference ref3 = ref1;
106 REPORT_ERROR_STATIC(ErrorManagement::Information, "Number of references "
107 "pointing at %s is %d", ref1->GetName(), ref1.NumberOfReferences());
108 Function(ref3);
109 REPORT_ERROR_STATIC(ErrorManagement::Information, "Number of references "
110 "pointing at %s is %d", ref1->GetName(), ref1.NumberOfReferences());
111
112 return 0;
113}
This example shows how the ReferenceT can be used to verify compliance of the class name against the expected class type (or derived interface). Note that the class name “PIDEx1”’ is compatible with ControllerEx1.
1/**
2 * @file ReferencesExample3.cpp
3 * @brief Source file for class ReferencesExample3
4 * @date 14/03/2018
5 * @author Andre' Neto
6 *
7 * @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
8 * the Development of Fusion Energy ('Fusion for Energy').
9 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved
10 * by the European Commission - subsequent versions of the EUPL (the "Licence")
11 * You may not use this work except in compliance with the Licence.
12 * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
13 *
14 * @warning Unless required by applicable law or agreed to in writing,
15 * software distributed under the Licence is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17 * or implied. See the Licence permissions and limitations under the Licence.
18
19 * @details This source file contains the definition of all the methods for
20 * the class ReferencesExample3 (public, protected, and private). Be aware that some
21 * methods, such as those inline could be defined on the header file, instead.
22 */
23
24#define DLL_API
25
26/*---------------------------------------------------------------------------*/
27/* Standard header includes */
28/*---------------------------------------------------------------------------*/
29
30/*---------------------------------------------------------------------------*/
31/* Project header includes */
32/*---------------------------------------------------------------------------*/
33#include "AdvancedErrorManagement.h"
34#include "ClassRegistryDatabase.h"
35#include "ErrorLoggerExample.h"
36#include "Object.h"
37#include "Reference.h"
38#include "ReferenceT.h"
39#include "StreamString.h"
40
41/*---------------------------------------------------------------------------*/
42/* Static definitions */
43/*---------------------------------------------------------------------------*/
44
45/*---------------------------------------------------------------------------*/
46/* Method definitions */
47/*---------------------------------------------------------------------------*/
48namespace MARTe2Tutorial {
49/**
50 * @brief A MARTe::Object class will be automatically registered into the ClassRegistryDatabase.
51 */
52class MotorEx1: public MARTe::Object {
53public:
54 CLASS_REGISTER_DECLARATION()
55
56 /**
57 * @brief NOOP.
58 */
59MotorEx1 () {
60 property = 0u;
61 }
62
63 virtual ~MotorEx1() {
64 using namespace MARTe;
65 if (GetName() != NULL) {
66 REPORT_ERROR_STATIC(ErrorManagement::Information, "No more references "
67 "pointing at %s [%s]. "
68 "The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
69 }
70 }
71
72 /**
73 * A property.
74 */
75 MARTe::uint32 property;
76};
77
78CLASS_REGISTER(MotorEx1, "")
79
80class ControllerEx1: public MARTe::Object {
81public:
82 CLASS_REGISTER_DECLARATION()
83
84 /**
85 * @brief NOOP.
86 */
87ControllerEx1 () {
88 property2 = 0u;
89 }
90
91 virtual ~ControllerEx1() {
92 using namespace MARTe;
93 if (GetName() != NULL) {
94 REPORT_ERROR_STATIC(ErrorManagement::Information, "No more references "
95 "pointing at %s [%s]. The Object "
96 "will be safely deleted.", GetName(), GetClassProperties()->GetName());
97 }
98 }
99
100 virtual void AFunction () {
101 using namespace MARTe;
102 REPORT_ERROR_STATIC(ErrorManagement::Information, "AFunction called @ %s.", GetName());
103 }
104
105 /**
106 * A property.
107 */
108 MARTe::uint32 property2;
109};
110
111CLASS_REGISTER(ControllerEx1, "")
112
113class PIDEx1: public ControllerEx1 {
114public:
115 CLASS_REGISTER_DECLARATION()
116
117 /**
118 * @brief NOOP.
119 */
120PIDEx1 () {
121 property3 = 0u;
122 }
123
124 virtual ~PIDEx1() {
125 using namespace MARTe;
126 REPORT_ERROR_STATIC(ErrorManagement::Information, "No more references pointing "
127 "at %s [%s]. The Object will be safely deleted.", GetName(), GetClassProperties()->GetName());
128 }
129
130 virtual void AFunction () {
131 using namespace MARTe;
132 REPORT_ERROR_STATIC(ErrorManagement::Information, "AFunction called @ %s.", GetName());
133 }
134 /**
135 * A property.
136 */
137 MARTe::uint32 property3;
138};
139
140CLASS_REGISTER(PIDEx1, "")
141}
142
143int main(int argc, char **argv) {
144 using namespace MARTe;
145 using namespace MARTe2Tutorial;
146 SetErrorProcessFunction(&ErrorProcessExampleFunction);
147
148 CCString className1 = "MotorEx1";
149 CCString className2 = "ControllerEx1";
150 CCString className3 = "PIDEx1";
151
152 //Automatically generate a new object instance based on the class name and on the
153 //correct Heap and with the template reference.
154 ReferenceT<MotorEx1> ref1(className1, GlobalObjectsDatabase::Instance()->GetStandardHeap());
155 if (ref1.IsValid()) {
156 ref1->SetName("MotorInstance1");
157 REPORT_ERROR_STATIC(ErrorManagement::Information, "Successfully created an "
158 "instance of %s", className1.GetList());
159 }
160
161 //This should fail because className2 is not of type MotorEx1
162 ReferenceT<MotorEx1> ref2(className2, GlobalObjectsDatabase::Instance()->GetStandardHeap());
163 if (!ref2.IsValid()) {
164 REPORT_ERROR_STATIC(ErrorManagement::Information, "As expected, could not create an "
165 "instance of %s", className2.GetList());
166 }
167
168 //Now it should work as the requested class name of is of the expected type (.
169 ReferenceT<ControllerEx1> ref3(className2, GlobalObjectsDatabase::Instance()->GetStandardHeap());
170 if (ref3.IsValid()) {
171 ref3->SetName("ControllerInstance1");
172 REPORT_ERROR_STATIC(ErrorManagement::Information, "Successfully created an "
173 "instance of %s", className2.GetList());
174 }
175
176 //This mechanism also works with compatible subclasses PIDEx1->ControllerEx1
177 ReferenceT<ControllerEx1> ref4(className3, GlobalObjectsDatabase::Instance()->GetStandardHeap());
178 if (ref4.IsValid()) {
179 ref4->SetName("PIDInstance1");
180 REPORT_ERROR_STATIC(ErrorManagement::Information, "Successfully created an "
181 "instance of %s using the ReferenceT<ControllerEx1>", className3.GetList());
182 ref4->AFunction();
183 }
184
185 return 0;
186}
Instructions on how to compile and execute the examples can be found here.