1. Creating C++ Code Generation Scripts

The purpose of this section is to present a series of C++ code generation scripts. Each script consists of script statements. The objective of each set of script statements is to generate 100% compilable code with no compilation errors. Each set of script statements generates compilable C++ statements. Each C++ statement consists of C++ keywords, operators, and identifiers. For example, one set of script statements generates the C++ function definitions. Another set of script statements generates a C++ copy constructor. These scripts show you the potential for automatically generating a great deal of compilable C++ source code. However, as a developer you do not need to generate a maximum amount of code for every class. You should only generate the amount of code that you actually need. For example, you do not need to generate a constructor with arguments for every class. You should decide what C++ features that you need and create or modify the C++ code generation scripts to generate exactly what you want and no more. In practice, we use a minimum code generation script, e.g. CPPHDMIN.SCT for header files and CPPFUMIN.SCT for source code files (.cpp) for each project and then selectively use a maximum code generation script for some classes, e.g. CPPHDMAX.SCT and CPPFUMAX.SCT. In this section we are presenting portions of CPPHDMAX.SCT and CPPFUMAX.CPP for maximum ANSI C++ code generation including the use of exceptions.




  1. Generating Compilable C++

To generate compilable code you must have a correct script, a correct model consisting of the diagram and specifications, and an adequate CASE tool scripting language (operators and variables). The basic process is shown below. First we create a class diagram as shown on the next page. In particular we enter the class names, attribute names, operation names, and relationship traversal path names, e.g. currentCellularPhone. Next we fill in the specification forms. We enter specific C++ information such as the attribute type int and the operation return type void. In scripting terms we are ensuring correct script variable values. For example, an incorrect script variable value would be the attribute type of INTEGER which is not a legal C++ data type. Next we examine the C++ code generation script to ensure that correct C++ keywords and operators are entered as script literals and that applicable script variables are used such as ATTRIBUTE_TYPE. Next we run the script to generate the C++ code. We do a visual check to look for any obvious compilation errors. Next we bring the C++ code files into a C++ environment and compile. If there are any compilation errors, then we correct the model information and/or the script to generate compilable C++.






Scripts are presented in the order of simple to complex:

- Generating the C++ Class Declaration in the Header File,

- Generating C++ Function Definitions in the Source Code File,

- Generating C++ Compiler Directives,

- Generating C++ Base and Derived Class Declarations,

- Generating C++ Symbolic const, typedef, and enum Declarations,

- Generating C++ Data Members and Accessor Functions,

- Generating One to One Aggregation Data Members and Accessor Functions,

- Generating One to One Association Data Members and Accessor Functions,

- Generating One to Many Aggregation Data Members and Accessor Functions,

- Generating One to Many Association Data Members and Accessor Functions,

- Generating Default Constructor and Destructor,

- Generating Constructor with Arguments,

- Generating the Copy Constructor,

- Generating the Assignment operator=,

- Generating the Equality operator==

- Generating Input Insertion operator>>,

- Generating Output Extraction operator<<,

The class diagram below shows the Car class with a generalization relationship (inheritance), one to one aggregation relationship, one to one association relationship, one to many aggregation relationship, and one to many association relationship.

There is a single script to generate the class declaration for each class on this diagram, e.g. CPPHDMAX.SCT. There is a single script to generate the function definitions for each class on this diagram, e.g. CPPFUMAX.SCT. In this section we will show sets of script statements and the generated C++ code for the Car class. The class diagram below with specification information is the basis for the generated C++ code in the following sections.

Figure Class Diagram Used for C++ Code Generation

After the class diagram is completed, we generate C++ using a C++ header file code generation script and a C++ function definition script. Then we compile the generated code, update the generated code as required, create a main function and then compile, link, and execute the project.

At this point we are ready to reverse the project to create a reversed class diagram as shown below. This reversed class diagram shows all original data members and function members plus the new generated data members and function members. For example, nullCellularPhone is a new generated data member. A new generated function member is setSpeed. This reversed diagram shows a single constructor per class. Actually, there are three overloaded constructors in each class, e.g. default constructor, constructor with arguments, and the copy constructor. The diagram show several overloaded operations with a trailing $, e.g. existsPassenger$. This indicates that there are multiple functions with the same name but different arguments. For example, there is an existsPassenger function with no arguments and an existsPassenger function with a pointer argument.

Figure Reversed Class Diagram from Generated C++

The main function used this example is listed below. This is a basic test case.

#include "car.h"

#include <iostream.h>

#include <cstring.h>

int main ()

{

Car car1; //Invokes default constructor

cin >> car1; //Invokes input function >>

cout << car1; //Invokes output function <<

int aSpeed, aNumber; //Create int variables

long aTotal; //Create long variable

car1.setspeed (55); //Invokes set accessor function

aSpeed = car1.getspeed(); //Invokes get accessor function

aSpeed = 65;

Car::settotalCarsBuilt (9999);//Invokes set accessor function for static data member

aTotal = Car::gettotalCarsBuilt(); //Invokes get accessor function for static data member

Car car2 (car1); //Invokes copy constructor

Car car3 (55, 0, 0); //Invokes constructor with arguments

car1 = car2; //Invokes assignment operator

//Invokes equality operator

if (car1 == car3) cout << "Cars are equal." << "\n";

else cout << "Cars are not equal." << "\n";

try {

car1.start(); } //Invokes redefined virtual function

catch (string startError) { cout << "Start Error"; }

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.operate(55); } //Invokes a function

catch (string operateError) { cout << "Operate Error"; }

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.stop(); } //Invokes a function

catch (string stopError) { cout << "Stop Error"; }

catch (...) { cout << "Unknown Error" << endl; }

Motor motor1; //Create motor objects

car1.setMotor(motor1); //Invokes set accessor function to set aggregation part

const Motor motor2 = car1.getMotor(); //Invokes get accessor function to get aggregation part

CellularPhone phone1; //Create phone objects

car1.setCellularPhone (&phone1); //Invokes set accessor function for association object

try {

car1.makePhoneCall(55555); } //Invokes traversal function to access association object

catch (string makePhoneCallError) { cout << "Make Phone Call Error"; }

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.receivePhoneCall(); } //Invokes traversal function to access association object

catch (string receivePhoneCallError) { cout << "Make Phone Call Error"; }

catch (...) { cout << "Unknown Error" << endl; }

const CellularPhone phone2 = *car1.getCellularPhone ();//Invokes get accessor function to

//get association object

int phoneStatus = car1.existsCellularPhone (); //Invokes exists function for association object

phoneStatus = car1.existsCellularPhone (&phone1);//Invokes exists function for association object

try {

car1.removeCellularPhone();} //Invokes remove function for association object

catch (string noCellularPhone) { cout << "No Cellular Phone"; }

catch (...) { cout << "Unknown Error" << endl; }

Tire tireArray[4]; //Creates array of tire objects

Tire* pTireArray = tireArray; //Creates pointer to the array of tire objects

pTireArray = (Tire*)car1.getTireCollection();//Invokes get accessor function

//for collection of aggregation objects

car1.setTireCollection (pTireArray);//Invokes set accessor function for

//collection of aggregation objects

const Tire tire1; //Creates tire objects

tire1 = car1.getFirstTire(); //Invokes get accessor function for 1:M aggregation object

int tireStatus = car1.existsTire (tire1);//Invokes exists function for 1:M aggregation object

Passenger passengerArray[4]; //Creates array of passengers

Passenger* pPassengerArray = passengerArray; //Creates pointer to array of passenger objects

pPassengerArray = (Passenger*)car1.getPassengerCollection(); //Invokes get accessor function

//for collection of association objects

car1.setPassengerCollection (pPassengerArray); //Invokes set accessor function

//for collection of association objects

Passenger passenger1, passenger2, passenger3, passenger4; //Create passenger objects

try {

car1.addPassenger(&passenger1); } //Invokes add function for 1:M association object

catch (string PassengerCollectionFull) { cout << "Passenger Collection Full" << endl;}

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.addPassenger(&passenger2); } //Invokes add function for 1:M association object

catch (string PassengerCollectionFull) { cout << "Passenger Collection Full" << endl;}

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.addPassenger(&passenger3); } //Invokes add function for 1:M association object

catch (string PassengerCollectionFull) { cout << "Passenger Collection Full" << endl;}

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.addPassenger(&passenger4); } //Invokes add function for 1:M association object

catch (string PassengerCollectionFull) { cout << "Passenger Collection Full" << endl;}

catch (...) { cout << "Unknown Error" << endl; }

int passengerStatus;

passengerStatus = car1.existsPassenger (); //Invokes exists function for association object

passengerStatus = car1.existsPassenger (&passenger1); //Invokes exists function

//for association object

cin >> car1; //Invokes the >> operator to input text information

cout << car1; //Invokes the << operator to output text information

try {

car1.removeLastPassenger (); } //Invokes removeLast function for 1:M association object

catch (string noPassengerError) { cout << "No Passenger Error" << endl; }

catch (...) { cout << "Unknown Error" << endl; }

try {

car1.removeAllPassengers(); } //Invokes removeAll function for 1:M association object

catch (string noPassengerError) { cout << "No Passenger Error" << endl; }

catch (...) { cout << "Unknown Error" << endl; }

return 0; //Default destructor is invoked

}

Sample output of running the program is shown below.

Figure Screen Shot of the Car Simulation Program Execution
  1. C++ Code Generation Script Variables

C++ code generation scripts use a number of specific C++ script variables in the CASE tool. The specific C++ script variables are required to generate specific C++ keywords. In addition to the script variables previously presented, the following specific C++ script variables are used:

BASE_CLASS Prints superclass name for a class

INCLUDE_FILE Prints name of include file

CLASS_LIBRARY_BASE_CLASS Prints name of a library base class, e.g. CObject

CPP_ATTRIBUTE_CONSTANT Prints const if the attribute is checked as a const attribute

CPP_ATTRIBUTE_STATIC Prints static if the attribute is checked as a static attribute

CPP_OPERATIONS Prints all operations for a class in C++ format

CPP_OPERATION_VIRTUAL Prints virtual if operation is checked as a virtual function

CPP_OPERATION_CONSTANT Prints const if operation is checked as a const function

CPP_OPERATION_STATIC Prints static if operation is checked as a static function

CPP_OPERATION_PURE_VIRTUAL Prints = 0 if operation is checked as a pure virtual function

CPP_OPERATION_PARAMETERS Prints operation parameters in C++ format, e.g.

Class/Type Name Parameter Name - int aNumber

OPERATION_CPP_VIRTUAL_BASE_CLASS Prints virtual if a virtual function appears in the class

  1. C++ Code Generation Script Operators

These scripts make extensive use of operators for concatenation, repeat, and symbol deletion. These operators are required to generate compilable code. The following are the CASE tool script operators used in C++ code generation scripts:

Concatenation Operator $ - the symbol $ means to connect a literal and a variable. For example, Get$ATTRIBUTE_NAME connects the literal Get and the variable ATTRIBUTE_NAME. When executed, the result is Getspeed.

Repeat Operator [] - the symbol [] causes the variable or literal to be repeated. For example, [ATTRIBUTE_NAME] causes a list of attributes to be placed into the output file. Anything placed in between the brackets will be repeated for every variable.

DELETE_LAST_SYMBOL operator removes the trailing punctuation marks. This is useful in code generation. Example is class CLASS_NAME [:BASE_CLASS ,DELETE_LAST_SYMBOL].

TRUNCATE_EIGHT operator truncates a class name to eight characters using a vowel stripping algorithm. TRUNCATE_EIGHT_CHOP operator truncates a class name to eight characters by removing all characters after the eighth character. Example is #include "TRUNCATE_EIGHT$CLASS_NAME$_H". This is useful to create legal MS/DOS file names.

NO_REPEAT operator prints a literal or punctuation symbol once without repeating it. Example is class CLASS_NAME [NO_REPEAT: public BASE_CLASS].

LITERAL_SYMBOL operator treats a bracket [ as a literal. This is used for arrays. Example is LITERAL_SYMBOL[ 10 LITERAL_SYMBOL].

NO_RETURN operator keeps all information on a single line without a return. Example is class CLASS_NAME [NO_RETURN : public BASE_CLASS].

SCRIPT_NOREPEAT_HEADER_BEGIN and SCRIPT_NOREPEAT_HEADER_END operator prints the literals and script variables with these operators. Example is SCRIPT_NOREPEAT_HEADER_BEGIN Beginning of the Class Report SCRIPT_NOREPEAT_HEADER_END.

SCRIPT_NOREPEAT_FOOTER_BEGIN and SCRIPT_NOREPEAT_FOOTER_END operator prints the literals and script variables with these operators, (e.g. SCRIPT_NOREPEAT_FOOTER_BEGIN Ending of the Class Report SCRIPT_NOREPEAT_FOOTER_END). Do not place any script variables within these statements.

SELECT_WHEN, LOGICAL_NOT, ==, !=, ATTRIBUTE_IS_CONSTANT, ATTRIBUTE_IS_STATIC, ATTRIBUTE_IS_INDEX and ATTRIBUTE_IS_NORMAL operators provide the capability to print the literals and script variables the follow the SELECT_WHEN if the condition is true, (e.g.

SELECT_WHEN ATTRIBUTE_IS_CONSTANT [ATTRIBUTE_NAME],

SELECT_WHEN ATTRIBUTE_IS_STATIC [ATTRIBUTE_NAME],

SELECT_WHEN ATTRIBUTE_IS_NORMAL [ATTRIBUTE_NAME],

SELECT_WHEN ATTRIBUTE_IS_INDEX [ATTRIBUTE_NAME],

SELECT_WHEN ATTRIBUTE_ACCESS == private [ATTRIBUTE_NAME],

SELECT_WHEN OPERATION_ACCESS == public [ATTRIBUTE_NAME],

SELECT_WHEN OPERATION_ACCESS != public [ATTRIBUTE_NAME],

SELECT_WHEN OPERATION_IS_PROCEDURE [OPERATION_NAME],

SELECT_WHEN OPERATION_IS_FUNCTION [OPERATION_NAME]

SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [ATTRIBUTE_NAME])

NO_OUTPUT_BEGIN and NO_OUTPUT_END operators provide the capability to place comments in scripts that do not print out in the script output. e.g. NO_OUTPUT_BEGIN. This script generates a text report listing class information NO_OUTPUT_END. Warning - do not place an script variables inside these operators. Place only literals inside these operators.

CAPITALIZE_ALL capitalizes all letters for include file names, e.g. #ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS$_H.

STRIP_TO_CAPITAL strips lower case letters prior to a capital letter in class names, e.g. #ifndef __$STRIP_TO_CAPITAL$TRUNCATE_EIGHT$CLASS$_H.

These operators are required to generate compilable C++. Unfortunately, these operators make the scripts difficult to read. To understand each script you should follow these steps:

1 - Identify the literals that are generally upper and lower case, e.g. Class:

2 - Identify the script variables that are upper case, e.g. CLASS_NAME,

3 - Identify the repeat operator [] to see where multiple entries will be generated,

4 - Identify the other operators, e.g. DELETE_LAST_SYMBOL,

5 - Compare each script statement with the generated output, e.g. Class: CLASS_NAME generates Class: Car,

Once you understand the script, then you can add, modify or delete script statements to generate exactly what you need.

  1. Generating the C++ Class Declarations in the Header File (.h)

The purpose of this introductory script is to generate an ANSI C++ class declaration in a header file. These script statements are part of the CPPHDMAX.SCT code generation script. The class declaration consists of C++ data member declarations and C++ function member definitions. From the class diagram, attributes become C++ data members. Operations become C++ function members. The sample code generation script, class diagram, and generated C++ code are shown below. To understand the script it is best to compare the script statements and the generated output. This script generates the following:

- #ifndef, #define, and #endif statement,

- class declaration, e.g. class Car { },

- data member declarations, e.g. int speed;

- function member declarations, e.g. void operate (int aSpeed);

As shown below this script interpreter reads in a script statement of literals, operators, and script variables. It inputs values for each script variable and outputs C++ statements for the class declaration. For example, the interpreters reads in the script statement #define __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H. It then inputs the value of the script variable CLASS_NAME, e.g. Car. It inserts the value and outputs the C++ statement. The generated output is #define __CAR_H.







This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows the major script variables used in the C++ code generation script to create the class declaration. It shows the CLASS_NAME, ATTRIBUTE_NAME, and OPERATION_NAME script variables. It shows the #define statement. The class diagram on the right shows sample values of the script variables, e.g. the define statement, class name Car, the attribute name speed, and the operation name operate. These values appear in the generated C++ statements.

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Class Declarations

// Class: CLASS_NAME //ANSI C++

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H //Required for CLASS_NAME class

#define __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

class CLASS_NAME[NO_RETURN NO_REPEAT: NO_REPEAT public BASE_CLASS ,DELETE_LAST_SYMBOL] CLASS_LIBRARY_BASE_CLASS

{ SELECT_WHEN ATTRIBUTE_ACCESS == private [ATTRIBUTE_TYPE ATTRIBUTE_NAME$;]

SELECT_WHEN OPERATION_ACCESS == private

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME

(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL;

]

protected:

SELECT_WHEN ATTRIBUTE_ACCESS == protected [ATTRIBUTE_TYPE ATTRIBUTE_NAME$;]

SELECT_WHEN OPERATION_ACCESSS == protected

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME

(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL;

]

public:

SELECT_WHEN ATTRIBUTE_ACCESS == public [ATTRIBUTE_TYPE ATTRIBUTE_NAME$;]

SELECT_WHEN OPERATION_ACCESSS == public

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME

(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL;

]

};

#endif

Generated C++ Class Declaration in the Header File for Car Class

// Class: Car //ANSI C++

#ifndef __CAR_H //Required for current class

#define __CAR_H

class Car : public Vehicle

{

int speed;

protected:

public:

void operate (int aSpeed);

};

#endif

  1. Generating the C++ Function Definitions - Source Code File (.cpp)

The purpose of this script is to generate function definitions in a source code file (.cpp file). These script statements are part of the CPPFUMAX.SCT code generation script. The script generates the function definitions of functions declared in the class declaration. The function definition consists of the following: return type, function name, function arguments, and function code statements. This script generates the following:

- #include statement to include the header file, e.g. #include "Car.h"

- function comments, e.g. Purpose:

- function declaration, e.g. int Car::operate(int aSpeed),

- function code if code has been entered in the function specification.

Script to Generate C++ Function Definitions - Source Code File

// Class: CLASS_NAME

//////////////////////////.cpp file/////////////////////////////////////////////////////

#include "$TRUNCATE_EIGHT$CLASS_NAME$.h"

// Functions for class CLASS_NAME

[

// Function: OPERATION_NAME

// Purpose: OPERATION_COMMENT1

// Parameters: CPP_OPERATION_PARAMETERS

// Comments: OPERATION_COMMENT2

OPERATION_RETURN_TYPE CLASS_NAME::OPERATION_NAME(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT

{

OPERATION_CODE

}

]

Generated C++ Function Definitions - Source Code File for Car Class

//////////////////////////.cpp file/////////////////////////////////////////////////////

#include "Car.h"

// Class: Car

// Functions for class Car

// Function: operate

// Purpose: To place the car at an operating speed

// Parameters: int aSpeed

// Comments:

void Car::operate(int aSpeed)

{

}

  1. Generating C++ Compiler Directives in the Header File (.h)

The purpose of these script statements is to generate the C++ compiler directives. These script statements are part of the CPPHDMAX.SCT code generation script. In the C++ header file, you must have include compiler directive statements for include files. The script generates include statements for the following files: iostream.h for cin and cout use, base class header file if the class is a derived class, any header files entered in the class specification form, one to one association class header files such as ClllrPhn.h, one to one aggregation part class header files such as Motor.h, one to many aggregation part header files such as Tire.h, and one to one association header files such as Passenge.h. The script operator TRUNCATE_EIGHT is used to reduce long class names to eight characters for the MS/DOS file system. For compilable code, the first eight characters of all class names should be unique.

Script to Generate C++ Include Statements

// Class: CLASS_NAME //ANSI C++

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H //Required for CLASS_NAME class

#define __$CAPITALIZE_ALL$TRUNCATE_EIGHT$CLASS_NAME$_H

#ifndef __IOSTREAM_H //Required for cin and cout

#include <iostream.h>

#endif

#ifndef __CSTRING_H //Required for CString class

#include <CString.h>

#endif

[

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$BASE_CLASS$_H //Required for BASE_CLASS class

#include "TRUNCATE_EIGHT$BASE_CLASS$.h"

#endif

]

[#include <INCLUDE_FILE> //Required for include files ]

[ //Required for 1:1 association classes

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$ASSOCIATION_ONE_CLASS$_H //ASSOCIATION_ONE_CLASS

#include "TRUNCATE_EIGHT$ASSOCIATION_ONE_CLASS.h"

#endif ]

[ //Required for 1:1 aggregation (part) classes

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$AGGREGATION_ONE_CLASS$_H //AGGREGATION_ONE_CLASS

#include "TRUNCATE_EIGHT$AGGREGATION_ONE_CLASS$.h"

#endif ]

[ //Required for 1:M association classes

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$ASSOCIATION_MANY_CLASS$_H //ASSOCIATION_MANY_CLASS

#include "TRUNCATE_EIGHT$ASSOCIATION_MANY_CLASS$.h"

#endif ]

[ //Required for 1:M aggregation (part) classes

#ifndef __$CAPITALIZE_ALL$TRUNCATE_EIGHT$AGGREGATION_MANY_CLASS$_H //AGGREGATION_MANY_CLASS

#include "TRUNCATE_EIGHT$AGGREGATION_MANY_CLASS$.h"

#endif ]

#endif

Generated C++ #include Statements in the Header File for Car Class

// Class: Car //ANSI C++

#ifndef __CAR_H //Required for Car class

#define __CAR_H

#ifndef __IOSTREAM_H //Required for cin and cout

#include <iostream.h>

#endif

#ifndef __CSTRING_H //Required for CString class

#include <CString.h>

#endif

#ifndef __VEHICLE_H //Required for Vehicle class

#include "Vehicle.h"

#endif

//Required for 1:1 association classes

#ifndef __CLLLRPHN_H //CellularPhone

#include "ClllrPhn.h"

#endif

//Required for 1:1 aggregation (part) classes

#ifndef __MOTOR_H //Motor

#include "Motor.h"

#endif

//Required for 1:M association classes

#ifndef __PASSENGR_H //Passenger

#include "Passengr.h"

#endif

//Required for 1:M aggregation (part) classes

#ifndef __TIRE_H //Tire

#include "Tire.h"

#endif

#endif

  1. Generating C++ Symbolic const, typedef, and enum Declarations in the Header File (.h)

The purpose of these script statements is to generate symbolic const, typedef and enum declaration statements in the C++ header file. These script statements are part of the CPPHDMAX.SCT code generation script. In using arrays it is useful to declare a symbolic const variable for the array limit. The script below generates a const variable maxNumberOf$AGGREGATION_MANY_CLASS and maxNumberOf$ASSOCIATION_MANY_CLASS to set the array limits for arrays which hold one to many aggregation objects and one to many association objects. The default value of 4 is assigned as the initial value of the const variables. This default value must be updated in the generated code to reflect the actual default value of the const variables. You must update the CLASS_USER1 and CLASS_USER2 input fields in the CASE tool class specification input form. Alternatively, create an constant attribute and generate the const declaration as discussed in the next section.

Script to Generate C++ const Declarations

NO_OUTPUT_BEGIN Use the CLASS_USER fields for typedef, enum, const declarations, e.g.

const int maxNumberOfTires = 4; NO_OUTPUT_END

CLASS_USER1

CLASS_USER2

Generated C++ Code - const Declarations for Car Class

const int maxNumberOfTires = 4; const int maxNumberOfPassengers = 4;

  1. Generating the C++ Base and Derived Class Declarations, Data Members, and Function Members

The purpose of this script is to generate C++ class declarations for base and derived classes. These script statements are part of the CPPHDMAX.SCT code generation script. On the class declaration, we show the generalization specialization relationship between a superclass and a subclass. In C++ terms, we show the inheritance relationship between a base class, e.g. Vehicle and a derived class, e.g. Car. The base class has a virtual functions, a pure virtual function, and a virtual destructor. This script generates the following:

- the base class declaration, e.g. class Vehicle

- the base class virtual functions, pure virtual function, and virtual destructor declarations, e.g. virtual void start(), virtual void operate (int aSpeed) = 0, and virtual ~Vehicle();

- the derived class declaration, e.g. class Car : public Vehicle

- data member declarations, e.g. int speed;

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows a class with script variables. It shows the major script variables and statements used in the C++ code generation script to declare base and derived classes. It shows the CLASS_NAME, ATTRIBUTE_NAME, and OPERATION_NAME. It shows the script variables CPP_OPERATION_VIRTUAL and CPP_OPERATION_PURE_VIRTUAL. If an operation is checked as being virtual or pure virtual in the operation specification, then these variables provide for the correct function declaration. For the sample virtual function, the script generates virtual void start (); For the sample pure virtual function the script generates virtual void operate() = 0; The script generates a virtual destructor, e.g. virtual ~Vehicle. As stated in the Microsoft Visual C++ Programmer's Guide "... declare the base class's destructor as virtual. This causes the destructors of all derived classes to be virtual... Then if delete is applied to a base class pointer, the appropriate destructor is called, no matter what type of object the pointer is pointing to." [Microsoft - 93]. This script generates the data members for 1 to 1 aggregation, 1 to 1 association, 1 to many aggregation, and 1 to many association.

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Class Declaration - .h File

class CLASS_NAME[NO_RETURN NO_REPEAT: NO_REPEAT public BASE_CLASS ,DELETE_LAST_SYMBOL] CLASS_LIBRARY_BASE_CLASS

{ SELECT_WHEN ATTRIBUTE_ACCESS == private

[CPP_ATTRIBUTE_STATIC CPP_ATTRIBUTE_CONSTANT ATTRIBUTE_TYPE ATTRIBUTE_NAME$; //Attribute data member]

[AGGREGATION_ONE_CLASS AGGREGATION_ONE_NAME$; //1:1 aggregation part data member]

[ASSOCIATION_ONE_CLASS$* ASSOCIATION_ONE_NAME$; //1:1 association object data member]

[ASSOCIATION_ONE_CLASS null$ASSOCIATION_ONE_CLASS;// Null association object for association object]

[int AGGREGATION_MANY_NAME$Index; //Index for array of 1:M aggregation part objects]

[ //1:M aggregation part data member

//Change C array to C++ collection class with iterator

AGGREGATION_MANY_CLASS AGGREGATION_MANY_NAME LITERAL_SYMBOL[maxNumberOf$AGGREGATION_MANY_CLASS$s LITERAL_SYMBOL];]

[int ASSOCIATION_MANY_NAME$Index; //Index for array of 1:M association objects]

[ //1:M association object data member

//Change C array to C++ collection class with iterator

ASSOCIATION_MANY_CLASS$* ASSOCIATION_MANY_NAME LITERAL_SYMBOL[maxNumberOf$ASSOCIATION_MANY_CLASS$s LITERAL_SYMBOL];]

[ // Null association object for initialization of association object data member

ASSOCIATION_MANY_CLASS$ null$ASSOCIATION_MANY_CLASS;]

SELECT_WHEN OPERATION_ACCESS == private

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL ; ]

protected:

SELECT_WHEN OPERATION_ACCESS == protected

[ CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL ; ]

SELECT_WHEN ATTRIBUTE_ACCESS == protected

[CPP_ATTRIBUTE_STATIC CPP_ATTRIBUTE_CONSTANT ATTRIBUTE_TYPE ATTRIBUTE_NAME$;]

public:

SELECT_WHEN ATTRIBUTE_ACCESS == public

[CPP_ATTRIBUTE_STATIC CPP_ATTRIBUTE_CONSTANT ATTRIBUTE_TYPE ATTRIBUTE_NAME$;]

SELECT_WHEN OPERATION_ACCESS == public

[CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL ; ]

OPERATION_CPP_VIRTUAL_BASE_CLASS ~ CLASS_NAME ( ) { }

//Destructor - Delete any pointer data members that used new in constructors

//Destructor should be virtual if and only if class contains at least one virtual function

//Objects destroyed in the reverse order of the construction order

};

Script to Generate C++ Function Definitions - .cpp File

#include "$TRUNCATE_EIGHT$CLASS_NAME$.h"

[

OPERATION_RETURN_TYPE CLASS_NAME::OPERATION_NAME(CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT

{ OPERATION_CODE

} ]

The following is the reversed class diagram from the generated C++ code.

Figure Reversed Class Diagram Showing Data and Function Members

Generated C++ Class Declaration for Vehicle Class - .h File

class Vehicle

{

protected:

float weight;

public:

virtual void start () ;

virtual void operate (int aSpeed) = 0 ;

virtual void stop () ;

virtual ~ Vehicle ( ) { }//Destructor - Delete any pointer data members that used new in constructors

//Destructor should be virtual if and only if class contains at least one virtual function

//Objects destroyed in the reverse order of the construction order

};

Generated C++ Function Definitions for Vehicle Class - .cpp File

//////////////////////////.cpp file/////////////////////////////////////////////////////

#include "Vehicle.h"

void Vehicle::start() {

}

void Vehicle::operate(int aSpeed) {

}

void Vehicle::stop(){

}

Generated C++ Class Declaration for Car Class - .h File

class Car : public Vehicle

{

int speed; //Attribute data member

static int totalCarsBuilt; //Attribute data member

float gasQuantity; //Attribute data member

const float minimumGasQuantity; //Attribute data member

Motor currentMotor; //1:1 aggregation part data member

CellularPhone* currentCellularPhone; //1:1 association object data member

CellularPhone nullCellularPhone;// Null association object for association object

int currentTiresIndex; //Index for array of 1:M aggregation part objects

//1:M aggregation part data member

//Change C array to C++ collection class with iterator

Tire currentTires [maxNumberOfTires ];

int currentPassengersIndex; //Index for array of 1:M association objects

//1:M association object data member

//Change C array to C++ collection class with iterator

Passenger* currentPassengers [maxNumberOfPassengers ];

// Null association object for initialization of association object data member

Passenger nullPassenger;

public:

void start () ;

void operate (int aSpeed) ;

void stop () ;

void makePhoneCall (long aNumber) ;

void receivePhoneCall () ;

void addPassenger (Passenger aPassenger) ;

void removePassenger (Passenger aPassenger) ;

~ Car ( ) { } //Destructor - Delete any pointer data members that used new in constructors

//Destructor should be virtual if and only if class contains at least one virtual function

//Objects destroyed in the reverse order of the construction order

};

Generated C++ Function Definitions for Car Class- .cpp File

#include "Car.h"

int Car::totalCarsBuilt = 0; //Static data member initialization

void Car::start() {

}

void Car::operate(int aSpeed) {

}

void Car::stop() {

}

void Car::makePhoneCall(long aNumber) {

}

void Car::receivePhoneCall() {

}

void Car::addPassenger(Passenger aPassenger) {

}

void Car::removePassenger(Passenger aPassenger) {

}

  1. Generating C++ Accessor Functions for Data Members

A C++ data member can represent an attribute, 1 to 1 aggregation traversal path, 1 to 1 association traversal path, 1 to many aggregation traversal path, and 1 to many association traversal path. You may create various accessor functions to get or set data member values.

  1. Generating C++ Accessor Functions for Data Members Representing Attributes

An attribute may be a normal data member, a static data member or a const data member. This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data members and accessor functions. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to declare data members and accessor functions. It shows the CLASS_NAME and ATTRIBUTE_NAME script variables. It shows the get$ATTRIBUTE_NAME and set$ATTRIBUTE_NAME script statements. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the attribute name speed, the get accessor function getspeed, and the set accessor function setspeed. As shown below a static data member is initialized outside the class declaration.

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values
  1. Generating C++ Accessor Functions for Data Members for One to One Aggregation

The purpose of these script statements is to generate C++ accessor function members to implement one to one aggregation relationships. These script statements are part of the CPPHDMAX.SCT code generation script. On the class declaration, we show a one to one aggregation relationship by connecting an aggregation assembly class, e.g. Car with an aggregation part class, e.g. motor. We show a relationship traversal name, e.g. currentMotor. In the aggregation assembly class, the script generates a non-static data member for each aggregation part class. In the Car class, the script generates a data member, e.g. Motor currentMotor. In the aggregation assembly class, the script generates get and set accessor functions for the aggregation part data member. In the Car class, the script generates the getMotor and setMotor accessor functions. The get accessor function returns a reference to the aggregation part data member, e.g. Motor& getMotor (). The set accessor function takes a reference argument, e.g. void setMotor (Motor& aMotor). You desire to have very strict encapsulation with no access to private data members. If so, then do not use these script statements.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to declare one to one aggregation data members and accessor functions. It shows the CLASS_NAME and AGGREGATION_ONE_NAME script variables. It shows the get$AGGREGATION_ONE_CLASS and set$AGGREGATION_ONE_CLASS script statements. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the traversal one to one aggregation data member currentMotor, the get accessor function getMotor, and the set accessor function setMotor.

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values
  1. Generating C++ Accessor Functions for Data Members for One to One Association

The purpose of these script statements is to generate C++ accessor function members to data members that implement one to one association relationships. These script statements are part of the CPPHDMAX.SCT code generation script. On the class declaration, we show a one to one association relationship by connecting a class, e.g. Car with an association class, e.g. CellularPhone. We show a relationship traversal name, e.g. currentCellularPhone. In the first class, the script generates a private non-static data member for each association. For example, in the Car class, the script generates a pointer data member, e.g. CellualarPhone* currentCellularPhone. In the Car class the script generates several accessor functions for the association data member. These are the get, set, remove, exists, and exists for a specific association object. These accessor functions either take a pointer argument or return a pointer. You may desire to have very strict encapsulation with no access to private data members. If so, then do not use these script statements.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to declare one to one association data members and accessor functions. It shows the CLASS_NAME and ASSOCIATION_ONE_NAME script variables. It shows the get$ASSOCIATION_ONE_CLASS, set$ASSOCIATION_ONE_CLASS, remove$ASSOCIATION_ONE_CLASS, exists$ASSOCIATION_ONE_CLASS, and exists$ASSOCIATION_ONE_CLASS (ASSOCIATION_ONE_CLASS$*) script statements. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the traversal one to one association data member *currentCellularPhone, the get accessor function getCellularPhone, the set accessor function setCellularPhone, the remove function removeCellularPhone, the exists function existsCellularPhone, and the exists function existsCellularPhone (CellularPhone*).

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values
  1. Generating C++ Accessor Functions for Data Members for One to Many Aggregation

The purpose of these script statements is to generate C++ and accessor function members to data members that implement one to many aggregation relationships. These script statements are part of the CPPHDMAX.SCT code generation script. On the class declaration, we show a one to many aggregation relationship by connecting an aggregation assembly class, e.g. Car with an aggregation part class, e.g. Tire. We show a relationship traversal name, e.g. currentTires. In the aggregation assembly class, the script generates a private non-static array data member for each aggregation part class. In the Car class, the script generates an array data member, e.g. Tire currentTires[maxNumberOfTires]. In the aggregation assembly class, the script generates getCollection and setCollection accessor functions for the aggregation part data member. The script generates the removeFirst and exists accessor functions. The getCollection accessor function returns a pointer to the first element of the array. The setCollection accessor function takes a pointer to the first element of the passed array. You may desire to have very strict encapsulation with no access to private data members. If so, then do not use these script statements.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to declare one to many aggregation data members and accessor functions. It shows the CLASS_NAME and AGGREGATION_MANY_NAME script variables. It shows the get$AGGREGATION_MANY_CLASS$Collection, get$AGGREGATION_MANY_CLASS$Collection, getFirst$AGGREGATION_MANY_CLASS, and exits$AGGREGATION_MANY_CLASS script statements. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the traversal one to many aggregation data member currentTires[maxNumberOfTires], the get accessor function getTireCollection, the set accessor function setTireCollection, the getFirstTire function, and the exists function existsTire.

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values
  1. Generating C++ Accessor Functions for Data Members for One to Many Association

The purpose of these script statements is to generate C++ and accessor function members to data members that implement one to many association relationships. These script statements are part of the CPPHDMAX.SCT code generation script. On the class declaration, we show a one to many association relationship by connecting a class, e.g. Car with an association class, e.g. Passenger. We show a relationship traversal name, e.g. currentPassenger. In the first class, the script generates a private non-static array data member for each association class. For example, in the Car class, the script generates an array data member, e.g. Passenger currentPassengers[maxNumberOfPassengers]. In the first class, the script generates getCollection and setCollection accessor functions for the association data member. The script generates the add, getFirst, removeFirst, removeAll, exists, and exists for a specific object functions. The getCollection accessor function returns a pointer to the first element of the array. The setCollection accessor function takes a pointer to the first element of the passed array. You may desire to have very strict encapsulation with no access to private data members. If so, then do not use the getCollection and setCollection script statements.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to declare one to many association data members and accessor functions. It shows the CLASS_NAME and ASSOCIATION_MANY_NAME script variables. It shows the get$ASSOCIATION_MANY_CLASS$Collection, set$ASSOCIATION_MANY_CLASS$Collection, getFirst$ASSOCIATION_MANY_CLASS, removeLast$ASSOCIATION_MANY_CLASS, exists$ASSOCIATION_MANY_CLASS, and exists$ASSOCIATION_MANY_CLASS (ASSOCIATION_MANY_CLASS$*) script statements. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the traversal one to many association data member currentPassengers[maxNumberOfPassengers], the get accessor function getPassengerCollection, the set accessor function setPassengerCollection, the add function addPassenger, the getFirst function getFirstPassenger, the removeLast function removeLastPassenger, the remove All function removeAllPassengers, the exists function existsPassenger, and the exists function existsPassenger (Passenger*).

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Accessor Functions for Data Members in the Header File

SELECT_WHEN ATTRIBUTE_IS_NORMAL

[ //Get accessor function for non-static attribute data member

ATTRIBUTE_TYPE get$ATTRIBUTE_NAME$() const

{ return ATTRIBUTE_NAME$;

} ]

SELECT_WHEN ATTRIBUTE_IS_NORMAL

[ //Set accessor function for non-static attribute data member

void set$ATTRIBUTE_NAME (const ATTRIBUTE_TYPE a$ATTRIBUTE_NAME$)

{ ATTRIBUTE_NAME = a$ATTRIBUTE_NAME$;

} ]

SELECT_WHEN ATTRIBUTE_IS_STATIC

[ //Get accessor function for static attribute data member

static ATTRIBUTE_TYPE get$ATTRIBUTE_NAME$()

{ return ATTRIBUTE_NAME$; } ]

SELECT_WHEN ATTRIBUTE_IS_STATIC

[ //Set accessor function for static attribute data member

static void set$ATTRIBUTE_NAME ( const ATTRIBUTE_TYPE a$ATTRIBUTE_NAME$)

{ ATTRIBUTE_NAME = a$ATTRIBUTE_NAME$;

} ]

SELECT_WHEN ATTRIBUTE_IS_CONSTANT

[ //Get accessor function for constant attribute data member

ATTRIBUTE_TYPE get$ATTRIBUTE_NAME$()

{ return ATTRIBUTE_NAME$;

} ]

[ //Get accessor function for 1:1 aggregation part data member

const AGGREGATION_ONE_CLASS$& get$AGGREGATION_ONE_CLASS$() const

{ return AGGREGATION_ONE_NAME$;

} ]

[ //Set accessor function for 1:1 aggregation part data member

void set$AGGREGATION_ONE_CLASS (const AGGREGATION_ONE_CLASS$& a$AGGREGATION_ONE_NAME$)

{ AGGREGATION_ONE_NAME = a$AGGREGATION_ONE_NAME$;

} ]

[ //Get accessor function for 1:1 association object data member

const ASSOCIATION_ONE_CLASS$* get$ASSOCIATION_ONE_CLASS$() const

{ return ASSOCIATION_ONE_NAME$;

} ]

[ //Set accessor function for 1:1 association object data member

void set$ASSOCIATION_ONE_CLASS ($ASSOCIATION_ONE_CLASS$* const a$ASSOCIATION_ONE_NAME$)

{ ASSOCIATION_ONE_NAME = a$ASSOCIATION_ONE_NAME$;

} ]

[ //Remove function for 1:1 association object data member

//Warning delete ASSOCIATION_ONE_NAME object if dynamic object

void remove$ASSOCIATION_ONE_CLASS$(); //throw (string) ]

[ //Exists function for 1:1 association object data member

int exists$ASSOCIATION_ONE_CLASS$() const; ]

[ //Exists function with argument for 1:1 association object data member

int exists$ASSOCIATION_ONE_CLASS ($ASSOCIATION_ONE_CLASS$* const a$ASSOCIATION_ONE_NAME$) const; ]

[ //Get accessor function for 1:M aggregation collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns pointer to the 1st element of the C array NO_OUTPUT_END

const AGGREGATION_MANY_CLASS$* get$AGGREGATION_MANY_CLASS$Collection () const ; ]

[ //Set accessor function for 1:M aggregation collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Parameter is pointer to the first element of the C array NO_OUTPUT_END

void set$AGGREGATION_MANY_CLASS$Collection ($AGGREGATION_MANY_CLASS$* const a$AGGREGATION_MANY_NAME$Collection); ]

[ //Get accessor function for 1:M aggregation part data member NO_OUTPUT_BEGIN

//Returns the first 1:M aggregation part in the array

//Change C array to C++ collection class with iterator NO_OUTPUT_END

const AGGREGATION_MANY_CLASS$& getFirst$AGGREGATION_MANY_CLASS$() const ; ]

[ //Exists function for 1:M aggregation part data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int exists$AGGREGATION_MANY_CLASS (const AGGREGATION_MANY_CLASS$& a$AGGREGATION_MANY_CLASS$) const ; ]

[ //Get accessor function for 1:M association collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns pointer to 1st element of the C array NO_OUTPUT_END

const ASSOCIATION_MANY_CLASS$* get$ASSOCIATION_MANY_CLASS$Collection() const ; ]

[ //Set accessor function for 1:M association collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Parameter is pointer to 1st element of the C array NO_OUTPUT_END

void set$ASSOCIATION_MANY_CLASS$Collection ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$Collection); ]

[ //Add function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void add$ASSOCIATION_MANY_CLASS ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$); //throw (string) ]

[ //Remove function for 1:M association object data member

//Warning delete ASSOCIATION_MANY_NAME object if dynamic object NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void removeLast$ASSOCIATION_MANY_CLASS ( ) ;//throw (string) ]

[ //Remove all function for 1:M association object data member

//Warning delete ASSOCIATION_MANY_NAME object if dynamic object NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void removeAll$ASSOCIATION_MANY_CLASS$s ( ) ;//throw (string) ]

[ //Get accessor function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns the first 1:M association object pointer in the array NO_OUTPUT_END

const ASSOCIATION_MANY_CLASS$* getFirst$ASSOCIATION_MANY_CLASS$() const ;//throw (string) ]

[ //Exists function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int exists$ASSOCIATION_MANY_CLASS$() const ; ]

[ //Exists function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int exists$ASSOCIATION_MANY_CLASS ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$) const ; ]

SELECT_WHEN OPERATION_ACCESS == public

[CPP_OPERATION_VIRTUAL CPP_OPERATION_STATIC OPERATION_RETURN_TYPE OPERATION_NAME (CPP_OPERATION_PARAMETERS) CPP_OPERATION_CONSTANT CPP_OPERATION_PURE_VIRTUAL ; ]

Reversed Class Diagram Showing All Accessor Functions to Data Members

Figure Reversed Class Diagram Showing Accessor Functions

Generated C++ Accessor Functions for Data Members in Car Class Header File (.h File)

//Get accessor function for non-static attribute data member

int getspeed() const

{ return speed;

}

//Get accessor function for non-static attribute data member

float getgasQuantity() const

{ return gasQuantity;

}

//Set accessor function for non-static attribute data member

void setspeed (const int aspeed)

{ speed = aspeed;

}

//Set accessor function for non-static attribute data member

void setgasQuantity (const float agasQuantity)

{ gasQuantity = agasQuantity;

}

//Get accessor function for static attribute data member

static int gettotalCarsBuilt()

{ return totalCarsBuilt;

}

//Set accessor function for static attribute data member

static void settotalCarsBuilt ( const int atotalCarsBuilt)

{ totalCarsBuilt = atotalCarsBuilt;

}

//Get accessor function for constant attribute data member

float getminimumGasQuantity()

{ return minimumGasQuantity;

}

//Get accessor function for 1:1 aggregation part data member

const Motor& getMotor() const

{ return currentMotor;

}

//Set accessor function for 1:1 aggregation part data member

void setMotor (const Motor& acurrentMotor)

{ currentMotor = acurrentMotor;

}

//Get accessor function for 1:1 association object data member

const CellularPhone* getCellularPhone() const

{ return currentCellularPhone;

}

//Set accessor function for 1:1 association object data member

void setCellularPhone (CellularPhone* const acurrentCellularPhone)

{ currentCellularPhone = acurrentCellularPhone;

}

//Remove function for 1:1 association object data member

//Warning delete currentCellularPhone object if dynamic object

void removeCellularPhone(); //throw (string)

//Exists function for 1:1 association object data member

int existsCellularPhone() const;

//Exists function with argument for 1:1 association object data member

int existsCellularPhone (CellularPhone* const acurrentCellularPhone) const;

//Get accessor function for 1:M aggregation collection

const Tire* getTireCollection () const ;

//Set accessor function for 1:M aggregation collection

void setTireCollection (Tire* const acurrentTiresCollection);

//Get accessor function for 1:M aggregation part data member

const Tire& getFirstTire() const ;

//Exists function for 1:M aggregation part data member

int existsTire (const Tire& aTire) const ;

//Get accessor function for 1:M association collection

const Passenger* getPassengerCollection() const ;

//Set accessor function for 1:M association collection

void setPassengerCollection (Passenger* const aPassengerCollection);

//Add function for 1:M association object data member

void addPassenger (Passenger* const aPassenger); //throw (string)

//Remove function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void removeLastPassenger ( ) ;//throw (string)

//Remove all function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void removeAllPassengers ( ) ;//throw (string)

//Get accessor function for 1:M association object data member

const Passenger* getFirstPassenger() const ;//throw (string)

//Exists function for 1:M association object data member

int existsPassenger() const ;

//Exists function for 1:M association object data member

int existsPassenger (Passenger* const aPassenger) const ;

Script to Generate C++ Accessor Functions for Data Members in Souce Code File (.cpp file)

[ //Remove function for 1:1 association object data member

//Warning delete ASSOCIATION_ONE_NAME object if dynamic object

void CLASS_NAME::remove$ASSOCIATION_ONE_CLASS$() //throw (string)

{ string no$ASSOCIATION_ONE_CLASS$;

if ( ASSOCIATION_ONE_NAME == &null$ASSOCIATION_ONE_CLASS ) throw no$ASSOCIATION_ONE_CLASS$;

else ASSOCIATION_ONE_NAME = &null$ASSOCIATION_ONE_CLASS;

} ]

[ //Get accessor function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns the first 1:M association object pointer in the array NO_OUTPUT_END

const ASSOCIATION_MANY_CLASS$* CLASS_NAME::getFirst$ASSOCIATION_MANY_CLASS$() const //throw (string)

{ string ASSOCIATION_MANY_CLASS$CollectionEmpty;

if ( ASSOCIATION_MANY_NAME$Index == 0 ) throw ASSOCIATION_MANY_CLASS$CollectionEmpty;

else return ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ASSOCIATION_MANY_NAME$Index LITERAL_SYMBOL];

} ]

[ //Exists function for 1:1 association object data member

int CLASS_NAME::exists$ASSOCIATION_ONE_CLASS$() const

{ if ( ASSOCIATION_ONE_NAME == &null$ASSOCIATION_ONE_CLASS ) return 0; else return 1;

} ]

[ //Exists function with argument for 1:1 association object data member

int CLASS_NAME::exists$ASSOCIATION_ONE_CLASS ($ASSOCIATION_ONE_CLASS$* const a$ASSOCIATION_ONE_CLASS$) const

{ if ( ASSOCIATION_ONE_NAME == &null$ASSOCIATION_ONE_CLASS ) return 0;

else if ( *$ASSOCIATION_ONE_NAME == *a$ASSOCIATION_ONE_CLASS ) return 1;

else return 0;

} ]

[ //Get accessor function for 1:M aggregation collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns pointer to the 1st element of the C array NO_OUTPUT_END

const AGGREGATION_MANY_CLASS$* CLASS_NAME::get$AGGREGATION_MANY_CLASS$Collection () const

{ return AGGREGATION_MANY_NAME ;

} ]

[ //Set accessor function for 1:M aggregation collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Parameter is pointer to the first element of the C array NO_OUTPUT_END

void CLASS_NAME::set$AGGREGATION_MANY_CLASS$Collection ($AGGREGATION_MANY_CLASS$* const a$AGGREGATION_MANY_CLASS$Collection)

{ for (int i = 0; i < maxNumberOf$AGGREGATION_MANY_CLASS$s; i++) AGGREGATION_MANY_NAME LITERAL_SYMBOL[ i LITERAL_SYMBOL] = a$AGGREGATION_MANY_CLASS$Collection LITERAL_SYMBOL[ i LITERAL_SYMBOL];

} ]

[ //Exists function for 1:M aggregation part data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int CLASS_NAME::exists$AGGREGATION_MANY_CLASS (const AGGREGATION_MANY_CLASS$& a$AGGREGATION_MANY_CLASS$) const

{ for (int i = 0; i < maxNumberOf$AGGREGATION_MANY_CLASS$s; i++)

{ if ( AGGREGATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] == a$AGGREGATION_MANY_CLASS ) return 1;

}

return 0;

} ]

[ //Get accessor function for 1:M aggregation part data member NO_OUTPUT_BEGIN

//Returns the first 1:M aggregation part in the array

//Change C array to C++ collection class with iterator NO_OUTPUT_END

const AGGREGATION_MANY_CLASS$& CLASS_NAME::getFirst$AGGREGATION_MANY_CLASS$() const

{ return AGGREGATION_MANY_NAME LITERAL_SYMBOL[ 0 LITERAL_SYMBOL] ;

} ]

[ //Get accessor function for 1:M association collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Returns pointer to 1st element of the C array NO_OUTPUT_END

const ASSOCIATION_MANY_CLASS$* CLASS_NAME::get$ASSOCIATION_MANY_CLASS$Collection() const

{ return *$ASSOCIATION_MANY_NAME;

} ]

[ //Set accessor function for 1:M association collection NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator

//Parameter is pointer to 1st element of the C array NO_OUTPUT_END

void CLASS_NAME::set$ASSOCIATION_MANY_CLASS$Collection ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$Collection)

{ int i = 0;

for ( i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS ;

for ( i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ i LITERAL_SYMBOL] = &a$ASSOCIATION_MANY_CLASS$Collection LITERAL_SYMBOL[ i LITERAL_SYMBOL];

} ]

[ //Add function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void CLASS_NAME::add$ASSOCIATION_MANY_CLASS ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$) //throw (string)

{ string ASSOCIATION_MANY_CLASS$CollectionFull;

if ( ASSOCIATION_MANY_NAME$Index == maxNumberOf$ASSOCIATION_MANY_CLASS$s) throw ASSOCIATION_MANY_CLASS$CollectionFull;

else

{ ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ ASSOCIATION_MANY_NAME$Index LITERAL_SYMBOL] = a$ASSOCIATION_MANY_CLASS ;

ASSOCIATION_MANY_NAME$Index++;

}

} ]

[ //Remove function for 1:M association object data member

//Warning delete ASSOCIATION_MANY_NAME object if dynamic object NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void CLASS_NAME::removeLast$ASSOCIATION_MANY_CLASS ( ) //throw (string)

{ string ASSOCIATION_MANY_CLASS$CollectionEmpty;

if ( ASSOCIATION_MANY_NAME$Index == 0 ) throw ASSOCIATION_MANY_CLASS$CollectionEmpty;

else

{ ASSOCIATION_MANY_NAME$Index--;

ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ASSOCIATION_MANY_NAME$Index LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS ;

}

} ]

[ //Remove all function for 1:M association object data member

//Warning delete ASSOCIATION_MANY_NAME object if dynamic object NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

void CLASS_NAME::removeAll$ASSOCIATION_MANY_CLASS$s ( ) //throw (string)

{ string ASSOCIATION_MANY_CLASS$CollectionEmpty;

if ( ASSOCIATION_MANY_NAME$Index == 0 ) throw ASSOCIATION_MANY_CLASS$CollectionEmpty;

for (int i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS;

} ]

[ //Exists function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int CLASS_NAME::exists$ASSOCIATION_MANY_CLASS$() const

{ if ( ASSOCIATION_MANY_NAME LITERAL_SYMBOL[0 LITERAL_SYMBOL] == &null$ASSOCIATION_MANY_CLASS ) return 0; else return 1;

} ]

[ //Exists function for 1:M association object data member NO_OUTPUT_BEGIN

//Change C array to C++ collection class with iterator NO_OUTPUT_END

int CLASS_NAME::exists$ASSOCIATION_MANY_CLASS ($ASSOCIATION_MANY_CLASS$* const a$ASSOCIATION_MANY_CLASS$) const

{if (ASSOCIATION_MANY_NAME LITERAL_SYMBOL[ 0 LITERAL_SYMBOL] == &null$ASSOCIATION_MANY_CLASS) return 0;

for (int i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++)

{if ( ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] == a$ASSOCIATION_MANY_CLASS) return 1;

}

return 0; } ]

Generated C++ Accessor Functions for Data Members in Souce Code File (.cpp file) for Car Class

//Remove function for 1:1 association object data member

//Warning delete currentCellularPhone object if dynamic object

void Car::removeCellularPhone() //throw (string)

{ string noCellularPhone;

if ( currentCellularPhone == &nullCellularPhone ) throw noCellularPhone;

else currentCellularPhone = &nullCellularPhone;

}

//Get accessor function for 1:M association object data member

const Passenger* Car::getFirstPassenger() const //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

else return currentPassengers [currentPassengersIndex ];

}

//Exists function for 1:1 association object data member

int Car::existsCellularPhone() const

{ if ( currentCellularPhone == &nullCellularPhone ) return 0; else return 1;

}

//Exists function with argument for 1:1 association object data member

int Car::existsCellularPhone (CellularPhone* const aCellularPhone) const

{ if ( currentCellularPhone == &nullCellularPhone ) return 0;

else if ( *currentCellularPhone == *aCellularPhone ) return 1;

else return 0;

}

//Get accessor function for 1:M aggregation collection

const Tire* Car::getTireCollection () const

{ return currentTires ;

}

//Set accessor function for 1:M aggregation collection

void Car::setTireCollection (Tire* const aTireCollection)

{ for (int i = 0; i < maxNumberOfTires; i++) currentTires [ i ] = aTireCollection [ i ];

}

//Exists function for 1:M aggregation part data member

int Car::existsTire (const Tire& aTire) const

{ for (int i = 0; i < maxNumberOfTires; i++)

{ if ( currentTires [i ] == aTire ) return 1;

}

return 0;

}

//Get accessor function for 1:M aggregation part data member

const Tire& Car::getFirstTire() const

{ return currentTires [ 0 ] ;

}

//Get accessor function for 1:M association collection

const Passenger* Car::getPassengerCollection() const

{ return *currentPassengers;

}

//Set accessor function for 1:M association collection

void Car::setPassengerCollection (Passenger* const aPassengerCollection)

{ int i = 0;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [ i ] = &nullPassenger ;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [ i ] = &aPassengerCollection [ i ];

}

//Add function for 1:M association object data member

void Car::addPassenger (Passenger* const aPassenger) //throw (string)

{ string PassengerCollectionFull;

if ( currentPassengersIndex == maxNumberOfPassengers) throw PassengerCollectionFull;

else

{ currentPassengers [ currentPassengersIndex ] = aPassenger ;

currentPassengersIndex++;

}

}

//Remove function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void Car::removeLastPassenger ( ) //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

else

{ currentPassengersIndex--;

currentPassengers [currentPassengersIndex ] = &nullPassenger ;

}

}

//Remove all function for 1:M association object data member

//Warning delete currentPassengers object if dynamic object

void Car::removeAllPassengers ( ) //throw (string)

{ string PassengerCollectionEmpty;

if ( currentPassengersIndex == 0 ) throw PassengerCollectionEmpty;

for (int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

//Exists function for 1:M association object data member

int Car::existsPassenger() const

{ if ( currentPassengers [0 ] == &nullPassenger ) return 0; else return 1;

}

//Exists function for 1:M association object data member

int Car::existsPassenger (Passenger* const aPassenger) const

{ if ( currentPassengers [ 0 ] == &nullPassenger ) return 0;

for (int i = 0; i < maxNumberOfPassengers; i++)

{ if ( currentPassengers [i ] == aPassenger ) return 1;

}

return 0;

}

  1. Generating the C++ Default Constructor

The purpose of these script statements is to generate the C++ default constructor in the class declaration. These script statements are part of the CPPHDMAX.SCT code generation script. The default constructor initializes each data member. It initializes each attribute data member with the initial value in the attribute specification. It initializes each association data member to a nullAssociation object. Alternatively you may initialize each association data member pointer to zero. It initializes array indexes to zero. It initializes each association data member in the array of association objects to nullAssociation object. Alternatively you may initialize each pointer in the array of association objects to zero.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ default constructor. This information class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to define the default constructor. It shows the CLASS_NAME, ATTRIBUTE_NAME, AGGREGATION_ONE_NAME, ASSOCIATION_ONE_NAME, AGGREGATION_MANY_NAME, and ASSOCIATION_MANY_NAME. The class diagram on the left shows actual values of the script variables and script statements, e.g. class name Car, the attribute names speed, gasQuantity, minimumGasQuantity, currentCellularPhone, currentTires[maxNumberOfTires], and currentPassengers[maxNumberOfPassengers]. It is not necessary to explicitly put the one to one aggregation name in the default constructor. As stated in the Microsoft Visual C++ Programmer's Guide, "the compiler implicitly calls the default constructor for the member object before constructing the containing object." [Microsoft - 93]. Notice that the implementation uses the initializer list. As stated in the Microsoft Visual C++ Programmer's Guide "When you declare an object of a derived class, the compiler executes the constructor for the base class first and then executes the constructor for the derived class. ...You may omit the base initializer if the base class has a default constructor. As with member objects, however, you should use the base initializer syntax rather than perform redundant initialization. If you're defining a derived class that also has member objects, you can specify both a member initializer list and a base initializer list. However, you cannot define member initializers for member objects defined in the base class, because that would permit multiple initializations." [Microsoft - 93]

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Default Constructor in Class Declaration in the Header File

//Default constructor alternative to compiler provided default constructor

//Ensure correct initial values

//Initialization list has members in the order declared

//Association object data member pointers initialized to null association object

CLASS_NAME ();

Script to Generate C++ Default Constructor in Source Code File (.cpp file)

//Default constructor alternative to compiler provided default constructor

//Association object data member pointers initialized to null association object NO_OUTPUT_BEGIN

//Ensure correct initial values are entered in the Attribute Specification NO_OUTPUT_END

CLASS_NAME::CLASS_NAME ()

SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [NO_RETURN NO_REPEAT: ATTRIBUTE_NAME(ATTRIBUTE_INITIAL_VALUE),DELETE_LAST_SYMBOL]

{ [ASSOCIATION_ONE_NAME = &null$ASSOCIATION_ONE_CLASS; //Initialization to null association object ]

[AGGREGATION_MANY_NAME$Index = 0; //Index for array of 1:M aggregation part objects ]

[ASSOCIATION_MANY_NAME$Index = 0; //Index for array of 1:M association objects ]

//Initialization of array of 1:M association objects to null association objects

[for ( int i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS; ]

}

Generated C++ Default Constructor in Class Declaration in the Header File for Car Class

//Default constructor alternative to compiler provided default constructor

//Ensure correct initial values

//Initialization list has members in the order declared

//Association object data member pointers initialized to null association object

Car ();

Generated C++ Default Constructor in Souce Code File (.cpp file)

//Default constructor alternative to compiler provided default constructor

//Association object data member pointers initialized to null association object

Car::Car ()

: speed(0), gasQuantity(0), minimumGasQuantity(0)

{ currentCellularPhone = &nullCellularPhone; //Initialization to null association object

currentTiresIndex = 0; //Index for array of 1:M aggregation part objects

currentPassengersIndex = 0; //Index for array of 1:M association objects

//Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

  1. Generating the C++ Constructor with Arguments

The purpose of these script statements is to generate the C++ constructor with arguments. These script statements are part of the CPPHDMAX.SCT code generation script. The constructor with arguments initializes each attribute data member with the passed argument value. It also initializes the base class attribute data members. Optionally, the constructor with arguments initializes the association data member, the one to many aggregation data member collection, and the one to many association data member collection. This script uses the script variables graphically shown on the class diagram on the left to generate the C++ constructor with arguments. This class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to define the constructor with arguments. It shows the CLASS_NAME, ATTRIBUTE_NAME, AGGREGATION_ONE_NAME, ASSOCIATION_ONE_NAME, AGGREGATION_MANY_NAME, and ASSOCIATION_MANY_NAME. The class diagram on the right shows actual values of the script variables and script statements, e.g. class name Car, the attribute names speed, gasQuantity, minimumGasQuantity, currentCellularPhone, currentTires[maxNumberOfTires], and currentPassengers[maxNumberOfPassengers]. Notice that the implementation invokes the base class default constructor, e.g. : Vehicle (). Alternatively you could provide an argument list to provide specific data member values for base class data members. An alternate could be Car ( int aspeed, float agasQuantity, float aminimumGasQuantity , int aweight ) : speed(aspeed) , gasQuantity (agasQuantity), minimumGasQuantity (aminimumGasQuantity), Vehicle(aweight){...}. The const data member minimumGasQuantity must be initialized in the initializer list. David Papurt provides a description of the use of const data members in Inside the Object Model - The Sensible Use of C++ [Papurt - 95].

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Constructor with Arguments in Class Declaration

//Constructor with arguments

//Update to argument list to initialize base class data members,

//e.g. (int aNumber) : BaseClass (aNumber)

CLASS_NAME ( SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [NO_RETURN ATTRIBUTE_TYPE a$ATTRIBUTE_NAME,DELETE_LAST_SYMBOL] ) ;

Generated C++ Constructor with Arguments in Class Declaration in the Header File for Car Class

//Constructor with arguments

//Update to argument list to initialize base class data members and const data members

//e.g. (int aNumber) : BaseClass (aNumber) , constMinimumValue (aMinimumValue)

CLASS_NAME::CLASS_NAME ( SELECT_WHEN LOGICAL_NOT ATTRIBUTE_IS_STATIC [NO_RETURN ATTRIBUTE_TYPE a$ATTRIBUTE_NAME,DELETE_LAST_SYMBOL] )

[NO_RETURN NO_REPEAT: BASE_CLASS$() ,DELETE_LAST_SYMBOL]

SELECT_WHEN ATTRIBUTE_IS_CONSTANT [//NO_RETURN NO_REPEAT: ATTRIBUTE_NAME (a$ATTRIBUTE_NAME),DELETE_LAST_SYMBOL]

{ SELECT_WHEN ATTRIBUTE_IS_NORMAL [ATTRIBUTE_NAME = a$ATTRIBUTE_NAME; //Initialization of attributes ]

[AGGREGATION_MANY_NAME$Index = 0; //Index for array of 1:M aggregation part objects ]

[ASSOCIATION_MANY_NAME$Index = 0; //Index for array of 1:M association objects ]

[ASSOCIATION_ONE_NAME = &null$ASSOCIATION_ONE_CLASS; //Initialization to null association object ]

//Initialization of array of 1:M association objects to null association objects

[for ( int i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS; ]

}

Generated C++ Default Constructor in Class Declaration (.h file)

//Constructor with arguments

//Update to argument list to initialize base class data members,

//e.g. (int aNumber) : BaseClass (aNumber)

Car ( int aspeed, float agasQuantity, float aminimumGasQuantity ) ;

Generated C++ Default Constructor in Souce Code File (.cpp file)

//Constructor with arguments

//Update to argument list to initialize base class data members and const data members

//e.g. (int aNumber) : BaseClass (aNumber) , constMinimumValue (aMinimumValue)

Car::Car ( int aspeed, float agasQuantity, float aminimumGasQuantity )

: Vehicle() , minimumGasQuantity (aminimumGasQuantity)

{ speed = aspeed; //Initialization of attributes

gasQuantity = agasQuantity; //Initialization of attributes

currentTiresIndex = 0; //Index for array of 1:M aggregation part objects

currentPassengersIndex = 0; //Index for array of 1:M association objects

currentCellularPhone = &nullCellularPhone; //Initialization to null association object

//Initialization of array of 1:M association objects to null association objects

for ( int i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

}

  1. Generating the C++ Copy Constructor

These script statements are part of the CPPHDMAX.SCT code generation script. These script statements are part of the CPPHDMAX.SCT code generation script. The copy constructor initializes the new object with the value of the copy object. For example, we could initialize the new car2 object with the value of the already constructed car1 object.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ copy constructor. This class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to define the copy constructor. It shows the CLASS_NAME, ATTRIBUTE_NAME, AGGREGATION_ONE_NAME, ASSOCIATION_ONE_NAME, AGGREGATION_MANY_NAME, and ASSOCIATION_MANY_NAME. The class diagram on the right shows actual values of the script variables and script statements, e.g. class name Car, the attribute names speed, currentMotor, currentCellularPhone, currentTires[maxNumberOfTires], and currentPassengers[maxNumberOfPassengers]. The const data member is initialized in the initializer list - minimumGasQuantity (aCar.minimumGasQuantity). The base class copy constructor is invoked in the initializer list - : Vehicle (aCar). This copy constructor provides a "member by member" copy from the source object to the new object but does not copy pointers for association objects. As discussed by Grady Booch, there are many copy alternatives such as shallow and deep copy [Booch-94].

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ Copy Constructor in Class Declaration in the Header File

//Copy Constructor NO_OUTPUT_BEGIN

//Copy constructor alternative to compiler provided default copy constructor

//Copy alternatives for association objects:

//(1) initialize association object to nullAssociation Object

//(2) Shallow copy to copy pointers of association objects

//(3) Deep copy to create new association objects and copy values of association objects

//Commented out code assigns 1:1 and 1:M association object data member pointers for shallow copy

//Remove // if you desire to assign pointers NO_OUTPUT_END

CLASS_NAME (const CLASS_NAME$& a$CLASS_NAME );

Script to Generate C++ Copy Constructor in Source Code File (.cpp file)

//Copy constructor alternative to compiler provided default copy constructor NO_OUTPUT_BEGIN

//Update initializer list for const data members, e.g. : constMinimumValue (aCar.minimumValue)

//Copy alternatives for association objects:

//(1) initialize association object to nullAssociation Object

//(2) Shallow copy to copy pointers of association objects

//(3) Deep copy to create new association objects and copy values of association objects

//Commented out code assigns 1:1 and 1:M association object data member pointers for shallow copy

//Remove // if you desire to assign pointers NO_OUTPUT_END

CLASS_NAME::CLASS_NAME (const CLASS_NAME$& a$CLASS_NAME )

[NO_RETURN NO_REPEAT: BASE_CLASS (a$CLASS_NAME),DELETE_LAST_SYMBOL]

SELECT_WHEN ATTRIBUTE_IS_CONSTANT [//NO_RETURN NO_REPEAT: ATTRIBUTE_NAME (a$CLASS_NAME$.$ATTRIBUTE_NAME),DELETE_LAST_SYMBOL]

{int i = 0;

[ AGGREGATION_MANY_NAME$Index = 0; //Index for array of 1:M aggregation part objects ]

[ ASSOCIATION_MANY_NAME$Index = 0; //Index for array of 1:M association objects ]

SELECT_WHEN ATTRIBUTE_IS_NORMAL [ATTRIBUTE_NAME = a$CLASS_NAME$.$ATTRIBUTE_NAME;]

[ AGGREGATION_ONE_NAME = a$CLASS_NAME$.$AGGREGATION_ONE_NAME;]

[ ASSOCIATION_ONE_NAME = &null$ASSOCIATION_ONE_CLASS; //Initialization to null association object ]

[ //ASSOCIATION_ONE_NAME = a$CLASS_NAME$.$ASSOCIATION_ONE_NAME; //Commented out shallow copy]

[ for ( i = 0; i < maxNumberOf$AGGREGATION_MANY_CLASS$s; i++) AGGREGATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = a$CLASS_NAME$.$AGGREGATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] ; ]

[ for ( i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS; //Initialization of pointers to null association object ]

[ //Commented out shallow copy

[ //for ( i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = a$CLASS_NAME$.$ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] ; ]

}

Generated C++ Copy Constructor in Class Declaration for Car Class the Header File

//Copy Constructor

Car (const Car& aCar );

Generated C++ Copy Constructor in Source Code File (.cpp file) for Car Class

//Copy constructor alternative to compiler provided default copy constructor

Car::Car (const Car& aCar )

: Vehicle (aCar), : minimumGasQuantity (aCar.minimumGasQuantity)

{int i = 0;

currentTiresIndex = 0; //Index for array of 1:M aggregation part objects

currentPassengersIndex = 0; //Index for array of 1:M association objects

speed = aCar.speed;

gasQuantity = aCar.gasQuantity;

currentMotor = aCar.currentMotor;

currentCellularPhone = &nullCellularPhone; //Initialization to null association object

//currentCellularPhone = aCar.currentCellularPhone; //Commented out shallow copy

for ( i = 0; i < maxNumberOfTires; i++) currentTires [i ] = aCar.currentTires [i ] ;

for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger;

//Initialization of pointers to null association object

//Commented out shallow copy

//for ( i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = aCar.currentPassengers [i ] ;

}

  1. Generating the C++ operator= Assignment Operator

The purpose of these script statements is to generate the operator= assignment operator. These script statements are part of the CPPHDMAX.SCT code generation script. The operator= sets the value of the data members of an object with the value of data members of another object. For example, the statement car1 = car2 would set car1 data members with the value of car2 data members. This script uses the script variables graphically shown on the class diagram on the left to generate the C++ operator=. This class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to define the operator= operator. It shows the CLASS_NAME, ATTRIBUTE_NAME, AGGREGATION_ONE_NAME, ASSOCIATION_ONE_NAME, AGGREGATION_MANY_NAME, and ASSOCIATION_MANY_NAME. The class diagram on the right shows sample values of the script variables and script statements, e.g. class name Car, the attribute names speed, currentMotor, currentCellularPhone, currentTires[maxNumberOfTires], and currentPassengers[maxNumberOfPassengers]. This assignment operator provides a "member by member" copy from the source object to the new object but does not copy pointers for association objects. As discussed by Grady Booch, there are many assignment alternatives such as shallow and deep copy [Booch-94].

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members

Figure Class Diagram Showing Script Variables and Script Variable Values

Script to Generate C++ operator= Assignment Operator in Class Declaration in the Header File

//Operator= Assignment Operator

CLASS_NAME& operator= (const CLASS_NAME$& a$CLASS_NAME);

Script to Generate C++ operator= Assignment Operator in Source File

//Operator= Assignment Operator alternative to compiler provided operator= NO_OUTPUT_BEGIN

//Assignment alternatives for association objects:

//(1) initialize association object to nullAssociation Object

//(2) Shallow copy to copy pointers to association objects

//(3) Deep copy to copy value of association objects

//Commented out code copies pointers for 1:1 and 1:M association object data members for

//shallow copy Remove // if you desire to assign association object pointers for shallow copy NO_OUTPUT_END

CLASS_NAME& CLASS_NAME::operator= (const CLASS_NAME$& a$CLASS_NAME)

{ if (this == &a$CLASS_NAME) return *this;

int i = 0;

[ BASE_CLASS$::operator= (a$CLASS_NAME);]

SELECT_WHEN ATTRIBUTE_IS_NORMAL [ ATTRIBUTE_NAME = a$CLASS_NAME$.$ATTRIBUTE_NAME;]

[ AGGREGATION_ONE_NAME = a$CLASS_NAME$.$AGGREGATION_ONE_NAME;]

[ ASSOCIATION_ONE_NAME = &null$ASSOCIATION_ONE_CLASS; //Initialization to null association object ]

[ // ASSOCIATION_ONE_NAME = a$CLASS_NAME$.$ASSOCIATION_ONE_NAME;//Commented out shallow copy]

[ for (i = 0; i < maxNumberOf$AGGREGATION_MANY_CLASS$s; i++) AGGREGATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = a$CLASS_NAME$.$AGGREGATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] ; ]

[ for (i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = &null$ASSOCIATION_MANY_CLASS ; //Initialization of pointers to null association object ]

[ //for (i = 0; i < maxNumberOf$ASSOCIATION_MANY_CLASS$s; i++) ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] = a$CLASS_NAME$.$ASSOCIATION_MANY_NAME LITERAL_SYMBOL[i LITERAL_SYMBOL] ; ]

return *this;

Generated C++ operator= Assignment Operator in Car Class Declaration in the Header File

//Operator= Assignment Operator

Car& operator= (const Car& aCar);

Generated C++ operator= Assignment Operator in Car Class Source Code File

//Operator= Assignment Operator alternative to compiler provided operator=

Car& Car::operator= (const Car& aCar)

{ if (this == &aCar) return *this;

int i = 0;

Vehicle::operator= (aCar);

speed = aCar.speed;

gasQuantity = aCar.gasQuantity;

currentMotor = aCar.currentMotor;

currentCellularPhone = &nullCellularPhone; //Initialization to null association object

// currentCellularPhone = aCar.currentCellularPhone;//Commented out shallow copy

for (i = 0; i < maxNumberOfTires; i++) currentTires [i ] = aCar.currentTires [i ] ;

for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = &nullPassenger ;

//Initialization of pointers to null association object

//for (i = 0; i < maxNumberOfPassengers; i++) currentPassengers [i ] = aCar.currentPassengers [i ] ;

return *this;

}

  1. Generating the C++ operator== Equality Operator

The purpose of these script statements is to generate the C++ operator== equality operator. These script statements are part of the CPPHDMAX.SCT and CPPFUMAX.SCT code generation scripts. The operator== compares the value of the attribute data members and aggregation data members of one object with another object. If the values are equal, then the operator== returns 1. If the values are not equal, then the operator== returns 0.

This script uses the script variables graphically shown on the class diagram on the left to generate the C++ data and function members. This class diagram shows a class with script variables. It shows the major script variables used in the C++ code generation script to define the operator==. It shows the CLASS_NAME, ATTRIBUTE_NAME, AGGREGATION_ONE_NAME, ASSOCIATION_ONE_NAME, AGGREGATION_MANY_NAME, and ASSOCIATION_MANY_NAME. The class diagram on the right shows actual values of the script variables and script statements, e.g. class name Car, the attribute names speed, gasQuantity, currentMotor, and currentTires[maxNumberOfTires]. This equality operator provides a "member by member" comparison from one object to another object but does not compare pointers for association objects. As discussed by Grady Booch, there are many comparison based upon shallow and deep copy [Booch-94].

Major Script Variables for C++ Sample Values of Major Script Variables

Data and Function Members in C++ Data and Function Members