Attribute mapping for C++ (C++ code)
ACS generates an Attribute globally, within a namespace or within a class or struct definition:
• Globally if the Model or a Package (Folder mapping) owns the Attribute.
Example code:
#include "Folder1.h"
int Attribute1;
• Within a namespace if a Package (Namespace mapping) owns the Attribute.
Example code:
#include "Folder1.h"
namespace Folder1
{
int Attribute1;
}
• Within a class definition if a Class or Interface owns the Attribute, or within a struct definition if a Data Type owns the Attribute.
Example code:
class Class20
{
private:
// private attributes
int Attribute1;
};
Signal owned Attributes are not generated.
The attributes are organized by their Visibility, that is, Public, Protected, Private or Package.
Example code:
class foo
{
public:
int bar;
protected:
int foobar;
private:
char leaveMeAlone;
};
You can set up an Attribute to generate a #define. If an Attribute is Read Only with a Default specified but no Type specified, ACS generates the Attribute as a #define.
Example code:
#include "Folder1.h"
int Attribute1;
Reverser Notes: When reverse engineering the attributes of a class or a struct, the Reverser will reverse engineer an attribute as a Role if all of the following statements are true:
• The C++ attribute's data type can be identified as a class or struct in the code being reverse engineered.
• The C++ class or struct that is used as a data type can be reverse engineered, that is, it is a child of the root folder or a folder that is mapped to a Modeler Package.
• The Reverser cannot match the C++ attribute to an Attribute in the Model.
If a typed Part (Attribute) has an Association that has not been rolled up to the Part's type, ACS generates a nested class or struct that is derived from the Part's type. The nested class or struct defines the role that is modeled against the Part.
If a Class, Data Type or Interface owns Parts that are connected through an Association, initialization code is generated in the constructor for the class or struct.
The attribute declaration and initialization is derived from the properties of the Attribute and the tagged values set for Tag Definitions that are applied by the «C++ Attribute» stereotype.
Properties
• If the Visibility property of an Attribute is set to Public or Package:
◦ For an Attribute owned by a Class, Data Type or Interface, the attribute is declared as Public in the header file generated for the owning Class, Data Type or Interface.
◦ For an Attribute owned by the Model or a Package, the attribute is declared in the header file generated for the owning Model or Package.
• If the Visibility property of an Attribute is set to Protected or Private:
◦ For an Attribute owned by a Class or Data Type, the attribute is declared as Protected or Private in the header file generated for the owning Class or Data Type.
◦ For an Attribute owned by the Model or a Package, the attribute is declared in the implementation file generated for the owning Model or Package and marked as static.
Reverser Notes: When reverse engineering non-class or non-struct scoped attributes, the Visibility property of the Attribute is set is set to Public if the attribute is declared in the header file, or set to Private if the attribute is declared in the implementation file.
• The Behavior property is used with the Port property - for more information, see the Port property entry.
• If the Composite property is set to false (Composite check box cleared on Property Pages), a pointer to the type is generated.
Example code:
class Class20
{
private:
// private attributes
int * Attribute1;
};
• If the Data Type property is set, ACS generates the value as the attribute's data type, unless there is a value set for the C++ Function Pointer Return tag definition, in which case that value is used for the attribute's data type.
If no data type is specified, ACS generates int by default. If you want ACS to generate a different default in the absence of a data type for an Attribute, Parameter or Type Definition, change the default value that is specified in the
Cppgen.ini file.
Tell me more...Reverser Notes: When reverse engineering a attribute's data type:
◦ If the data type is modeled in the Model or is going to be reverse engineered to the Model, the Attribute's Data Type references the appropriate item.
◦ If the data type is not modeled in the Model and is not going to be reverse engineered to the Model, the Attribute's Data Type is set to the name of the data type (as text).
◦ If the data type is a function pointer, the Attribute's Data Type is not set and instead the C++ Function Pointer Return and C++ Function Pointer Parameter tag definitions are used to record the data type.
• If a Default Value is set, the value is generated either as a static attribute initializer or a constructor initializer.
Example code:
float foo::protectedat = 3.14;
foo::foo():
rSomebars(12),
publicat(true),
privateat('a'){}
• If the Description property has a value, ACS generates the description as a comment on the line before the attribute declaration.
• The Multiplicity of the Attribute determines the generated attribute's type:
◦ If the Multiplicity is 1 or TBD (Multiplicity property is set to 1), the type or a pointer to the type is used, depending on whether the Attribute is composite.
Example code:
// Association or non-composite Aggregation
// Forward declarations
class Class2;
class Class1
{
Private:
// Private Roles
Class2* rClass2;
};
// Composite Aggregation
// File dependencies
#include "Class2.h"
class Class1
{
private:
// private roles
Class2 rClass2;
};
◦ If the Multiplicity is a fixed size of two or more (set through User Defined), an array of the type or an array of pointers to the type is used, depending on whether the Attribute is composite.
Example code:
// Association or non-composite Aggregation
// File dependencies
#include "Class2.h"
class Class1
{
private:
// private roles
Class2* rClass2[4];
};
// Composite Aggregation
// File dependencies
#include "Class2.h"
class Class1
{
private:
// private roles
Class2 rClass2[4];
};
◦ If the Multiplicity specifies a range, a vector of the type or a vector of pointers to the type is used, depending on whether the Attribute is composite.
Example code:
// Association or non-composite Aggregation
// File dependencies
#include "Class2.h"
using namespace std;
#include <vector>
class Class1
{
private:
// private roles
vector< Class2* > rClass2;
};
// Composite Aggregation
// File dependencies
#include "Class2.h"
using namespace std;
#include <vector>
class Class1
{
private:
// private roles
vector< Class2 > rClass2;
};
• The Name property is generated as the name of the attribute in the code.
| ACS may modify the attribute name that is added to the code to make it valid for C++. You can specify the exact attribute name to add to the code through the CODE_GENERATION_NAME property of an Attribute.
Tell me more... |
• If the Read Only property is set to true (Read Only check box selected on Property Pages) and the value of the C++ CV Qualifier tag definition is blank, the const keyword is used. If the C++ CV Qualifier tag definition has a value, the Read Only property is ignored.
Example code:
class foo
{
const int bar; // Read Only = true
char leaveMeAlone; // Read Only = false
};
const int foobar = 10; // Read Only = true
• If a public Attribute is set up as Read Only to generate a const keyword, the C++ Storage Class tag definition determines whether the Default Value is defined in the header file or implementation file - when the C++ Storage Class tag definition is set to extern, the Default Value is defined in the implementation file.
• If the Storage property is set to On Class and the Attribute is scoped to a Class, Data Type or Interface, the static keyword is used and the attribute is initialized in the implementation file. For an Attribute that is not scoped to a Class, Data Type or Interface, the C++ Storage Class tag definition records whether the Attribute is a static.
Example code:
class foo
{
static int bar; // on Class
char leaveMeAlone; // On Instance
};
int foobar; // On class
• The Unique property is ignored.
Tag Definitions:
The following tag definitions are applied to an Attribute by the «C++ Attribute» stereotype:
• If the tagged value of the C++ Actual Template Parameters tag definition has been set, the value is used to generate the text between the angle brackets when the Attribute's type is a template class.
Example code:
map<string, int> myInts;
• If the tagged value of the C++ Anonymous Item tag definition is set to TRUE, it means that the attribute is used as an anonymous type and is generated with no name. This applies only to Class, Data Type and Interface scoped attributes (bitfields only).
Example code:
// An integer bitfield that is 4 bits wide and has no name.
// often used to pad a structure out.
struct bits
{
int : 4;
};
• Reverser Notes:When reverse engineering an attribute that is used as an anonymous type, ACS creates an Attribute in Modeler and sets its C++ Anonymous Item tag definition to TRUE. The name of the Attribute is as follows:
unnamed<integer to make unique>
• If the tagged value of the C++ Array Spec tag definition has been set, the set value is generated after the attribute name. Note that the value must include any brackets.
Example code:
class foo
{
char name[255];
};
#define AgeCount 20
int Ages[AgeCount];
int Multi[5][10];
Reverser Notes: When reverse engineering an initializer or array specification that uses a macro, the C++ Array Spec tag definition is set to the unpreprocessed text.
• If the tagged value of the C++ Bitfield tag definition has been set, the value is used to generate the bitfield width, that is, the value is preceded with a colon and is generated after the attribute name.
Example code:
int myInt : 4;
int anotherInt : WIDTH
• If the tagged value of the C++ CV Qualifier tag definition is set to const, volatile or const volatile, the selected keyword is generated before the data type. Note that if the C++ CV Qualifier tag definition is blank and the Read Only property is set to true (Read Only check box selected on Property Pages), the const keyword is used.
Example code:
const int foo;
volatile float pi;
const volatile char cvAttribute;
• If the tagged value of the C++ Function Pointer Return tag definitions has been set, the Attribute declaration is generated as follows using any parameters specified by the tagged value of the C++ Function Pointer Parameters:
Example code:
// C++ Function Pointer Return value is void
// C++ Function Pointer Parameters value are int and char *
void (* Attribute1)(int, char *);
<C++ Function Pointer Return> (<C++ Indirection><derived C++ Name>)(<C++ Function Pointer Parameters>);
• If the tagged value of the C++ Indirection tag definition has been set, the value is used as an indirection, that is, the value is generated after the data type and before the attribute name.
Example code:
const int* foo;
volatile float* const pi;
const volatile char* const * cvAttribute;
• If the tagged value of the C++ Linkage tag definition has been set, the value is generated as the attribute's linkage. For example, extern "C".
• If the tagged value of the C++ Non Member tag definition is set to TRUE and the Attribute is scoped to a Class or Data Type, the Attribute is declared in the owning Class' or Data Type's implementation file but is not a member of the owning class or struct. If the tagged value of the C++ Non Member tag definition is set to TRUE and the Attribute is scoped to an Interface, the Attribute is declared in the owning Interface's header file but is not a member of the owning class.
• If the Attribute is public, the attribute is marked as extern decl in the header file. If the Attribute is scoped to a Package, this Tag Definition is ignored.
Example code:
class foo
{
};
int bar;
• If the tagged value of the C++ Storage Class tag definition is set to auto, register, extern or mutable, the selected storage class keyword is generated. Note that in the context of an Attribute, only the extern and mutable values of the C++ Storage Class tag definition should be used.
Example code:
class foo
{
mutable int bar;
};
extern float pi;
If a public Attribute is set up as Read Only to generate a const keyword, the C++ Storage Class tag definition determines whether the Default Value is defined in the header file or implementation file - when the C++ Storage Class tag definition is set to extern, the Default Value is defined in the implementation file.
Reverser Notes: When reverse engineering an attribute that is marked as 'extern' and scoped to the Model or a Package, the Reverser sets the C++ Storage Class tag definition to 'extern', unless the code being reverse engineered also contains the attribute not marked as 'extern'. If the code being reverse engineered contains the attribute not marked as 'extern', the tagged value of the C++ Storage Class tag definition is set to blank.