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