Skip to main content

Tips and Tricks for the C++ Transformation using Rational Systems Developer or Rational Software Architect, Part 3: Constructing C++ specific models in UML

Vinod V. Uddaraju (vinod.varma@in.ibm.com), Staff Software Engineer, IBM Japan
Vinod Varma has been a developer working on IBM Rational modeling tools for the past 3 years. He has worked on various modeling tools like Rational Rose, Rational Software Architect, and Rational System Developer.
Pratima Gangalavoi (pratima.g@in.ibm.com), Systems Software Engineer, IBM Japan
Pratima Gangalavoi
Pratima Gangalavoi is a Systems Software Engineer working with Rational Software Architect and Rational Systems Developer at the IBM Rational Software Bangalore lab. She works on the C++ transform for those tools.

Summary:  This article (Part 3 of a series) provides you with tips to better understand how to construct C++ specific models in UML to generate the code when you run the UML to C++ transformation in IBM® Rational® Software Architect or IBM® Rational® Systems Developer.

View more content in this series

Date:  12 Feb 2008
Level:  Intermediate
Activity:  459 views
Comments:  

This article will show you how to model arrays, unions, abstract classes, default values for attributes, and so on. It also gives you some tips on how you can use Rational Software Architect features to further customize the code generated by the C++ transformation.

Modeling arrays in C++ with variable dimensions

This section discusses modeling arrays in C++ whose dimensions are specified as variables. To create a single dimensional array of the type a[m] (where m is an integer variable already defined and initialized), apply the cpp_type stereotype on the array variable a in the UML model. Next, set the array dimensions property of this stereotype to [m], as shown in Figure 1. To accomplish this, follow these steps:

  1. Select the UML class attribute that has to be modeled as an array.
  2. With the attribute still selected in the Project Explorer, switch to the Properties view, and then click the Stereotypes tab.
  3. Click the Apply Stereotypes button and select the cpp_type stereotype.
  4. Select the arrayDimensions property specified in the stereotype, and then specify the array dimensions, as shown in Figure1.

Figure 1. Specifying the dimensions for an array
Stereotypes tab of the Properties view

The related generated code is shown in Listing 1.


Listing 1. Generated code for the array attribute in Class1
                
#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1

    private:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int m;

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int attribute_int_array[m];
    public:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        Class1();

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        ~Class1();

};  //end class Class1

#endif


Modeling constructor, destructor, and copy constructor

This section discusses modeling the constructor, destructor, and copy constructor for a C++ class. To generate these for a C++ class named Class1, follow these steps:

  1. Create a UML class named Class1.
  2. Go to the Properties tab of the UML to C++ Transformation configuration wizard and select the Constructor, Destructor, and Copy Constructor options, as shown in Figure 2.

Figure 2. Modeling constructors, destructors, and copy constructors
tab with three sections

The related generated code is shown in Listing 2.


Listing 2. Code generated with constructors, destructors, and copy constructors
                
#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1
    public:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        Class1();

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        Class1(Class1 & arg);

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        ~Class1();

};  //end class Class1

#endif


Modeling the Assignment Operator

This section discusses modeling an assignment operator for a C++ class. To generate this assignment operator for a C++ class named Class1, perform these steps:

  1. Create a UML class with name Class1
  2. Go to the Properties tab of the Transformation Configuration wizard and select the Assignment option.

Figure 3. Modeling assignment operator for attributes
same tab with different options chosen

The related generated code is shown in Listing 3.


Listing 3. Code generated with assignment operator enabled
                
Source File:

#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1
    public:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        void operator =(const Class1 & arg);

};  //end class Class1

#endif

Body File:

#include "Class1.h" 
//Begin section for file Class1.cpp
//TODO: Add definitions that you want preserved
//End section for file Class1.cpp


//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
void Class1::operator =(const Class1 & arg) 
{
    //TODO Auto-generated method stub
}


Modeling getters and setters

This section discusses modeling getters and setters for an attribute in a C++ class. To generate these for a C++ attribute in a C++ class with name Class1, follow these steps:

  1. Create a UML class named Class1.
  2. Add a UML attribute named attribute1 and set its type to Integer.
  3. Then select the Getters and setters option in the Properties tab of the Transformation Configuration wizard.
  4. The transformation configuration provides you with the further options to make these getters and setters Inline or By reference, by selecting these properties in the transformation configuration under Getters and setters, as shown in Figure 4.

Figure 4. Modeling getters and setters for attributes
same tab with different options chosen

The related generated code is shown in Listing 4 (Inline) and Listing 5 (By reference).


Listing 4. Code generated with the Getters and setters and Inline option
                
#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1

    private:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int attribute1;
    public:

        //get attribute1
        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        inline int get_attribute1();

        //set attribute1
        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        inline void set_attribute1(int attribute1);

};  //end class Class1

#endif	      


Listing 5. Code generated with Getters and setters with the By reference option
                
#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1
{

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1

    private:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int attribute1;
    public:

        //get attribute1
        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int & get_attribute1();

        //set attribute1
        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        void set_attribute1(int & attribute1);

};  //end class Class1

#endif


Modeling inheritance for C++

Inheritance is an important feature in Object Oriented Programming, and UML provides a way to model it. To model inheritance, use the generalization relationship provided by the UML modeling palette, which is drawn from the inherited class to the base class. For example, consider constructing a model that has multiple inheritances. In the model shown in Figure 5, the UML class DerivedClass1 derives from the common class called BaseClass.


Figure 5. Modeling inheritance for C++
diagram with two classes

The related generated code is shown in Listing 6.


Listing 6. Generated code for a class DerivedClass1
                
#ifndef DERIVEDCLASS1_H
#define DERIVEDCLASS1_H
//Begin section for file DerivedClass1.h
//TODO: Add definitions that you want preserved
//End section for file DerivedClass1.h

#include "BaseClass.h"
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class DerivedClass1 : BaseClass
{
 
};

#endif

The C++ transformation also provides a stereotype, which can be applied to the generalization called cpp_generalization. This stereotype has properties under it that enable you to set the access specifier for the inheritance drawn, as shown in Figure 6.


Figure 6. Applying the cpp_generalization stereotype
choosing the Public value on the Stereotypes tab

The related generated code is shown in Listing 7.


Listing 7. Generated code for a class with cpp_generalization stereotype for DerivedClass1
                
#ifndef DERIVEDCLASS1_H
#define DERIVEDCLASS1_H
//Begin section for file DerivedClass1.h
//TODO: Add definitions that you want preserved
//End section for file DerivedClass1.h

#include "BaseClass.h"
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class DerivedClass1 : public BaseClass
{
 
};

#endif


Modeling unions for C++

This section helps you understand how to model unions using UML. The C++ transformation allows you to model this by providing a stereotype cpp_union. To create this, you must first apply the CPP transformation profile to the UML model that contains the union. To model a union, add a UML class to the model and add the cpp_union stereotype to it, as shown in Figure 7.


Figure 7. Modeling Unions for C++
stereotypes tab

This stereotype includes a property called isAnonymousUnion (as shown in Figure 7). This property can be set to True when you have to make a union anonymous. Anonymous unions have to be nested elements and cannot exist at the top level in a model.

The related generated code is shown in Listing 8.


Listing 8. Generated code for union Union1
                
#ifndef UNION1_H
#define UNION1_H
//Begin section for file Union1.h
//TODO: Add definitions that you want preserved
//End section for file Union1.h

//The top level union.
//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
union Union1
{

    //Begin section for Union1
    //TODO: Add attributes that you want preserved
    //End section for Union1

    public:
        //The anonymous union nested under Union1.
        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        union 
        {

            //Begin section for Union1::UnionNested
            //TODO: Add attributes that you want preserved
            //End section for Union1::UnionNested

        };  //end union 

    private:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        int attribute1;
    
};  //end union Union1

#endif


Modeling abstract classes in UML

Abstraction, as you know, is a very important Object Oriented concept, and the C++ transformation in Rational Software Architect and Rational System Developer allows you to model this in two ways. The first way to do this is to use the UML model element, Interface. The UML to C++ transformation treats this as an abstract class, and generates code to reflect the same. For example, consider the following model:

  1. Create a UML model that has classes named Car and Truck.
  2. These classes are instances of the vehicle type. Add an interface named Vehicle to the UML model.
  3. From the modeling palette, select the Interface Realization and draw these realizations from the classes to the interface.
  4. The model should look like that shown in Figure 8.

Figure 8. Modeling interfaces in C++
diagram with three elements

The code for the model element Vehicle is shown in Listing 9. Although the definitions for these interfaces are similar to those of classes, the operations under these interfaces are always abstract. You can implement abstraction by having realizations between the interfaces and the class implementations. In the generated code, these classes can extend the operations given by the interface. For example, in the above model, the car or truck class can override the default behavior for the getNumberOfTyres() and getVehicleNumber() operations to define their behaviors specific to their instance.


Listing 9. Generated Code for an interfaceVehicle
                 
                
#ifndef VEHICLE_H
#define VEHICLE_H
//Begin section for file Vehicle.h
//TODO: Add definitions that you want preserved
//End section for file Vehicle.h

class Vehicle
{

    //Begin section for Vehicle
    //TODO: Add attributes that you want preserved
    //End section for Vehicle
    public:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        virtual int getNumberofTyres() = 0;

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        virtual int getVehicleNumber() = 0;
};

#endif

The second way of modeling abstract classes is to have a UML class (for example, Class1). In the UML Properties tab for this class, select the Abstract button to make the class abstract, as shown in Figure 9.


Figure 9. Example for abstract class for C++
General tab in the Properties view

You would use abstract classes in cases where only a certain number of methods contained in it need to be implemented in instances derived from it, whereas you can use interfaces where all the methods need to be implemented by the instances of it, and hence the interface only tells the world what the abstraction of the object would look like.


Modeling default values for attributes in C++

When you have attributes in a class, you need to be able to initialize these attributes with some initial values. There is more than one way in which you can accomplish this. You can understand this with the help of examples that follow. First, construct a model having an attribute which is of type Integer array, whose dimensions are [3][4]. The default value for this attribute is set in the model, as shown in Figure 10.


Figure 10. Modeling default values for attributes in C++
Default value outlined by blue box

To construct a model, follow these steps:

  1. Create a UML model having a class of Class1.
  2. Add an attribute (attribute1) of type Integer to this class.
  3. Set default value for this attribute in the Properties tab for this, as shown in Figure 10.
  4. In the transformation configuration for this model as a source, enable the Constructor option in the Properties tab.
  5. The attributes then gets initialized in the constructor, as shown in the Listing 10.

Listing 10. Generated code for the constructor initializing the default value for an attribute
                 
                
#include "Class1.h" 
//Begin section for file Class1.cpp
//TODO: Add definitions that you want preserved
//End section for file Class1.cpp


//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
Class1::Class1() : 
attribute1(10) {
    //TODO Auto-generated method stub
}

The second way to create this model is as follows:

  1. Create a UML model having a class of Class1.
  2. Add an attribute (attribute1) of type Integer array to this class, and set the default value for it in the Properties tab for the attribute as shown in Figure 10.
  3. In the Properties tab for the attribute, select the Static check-box to make the attribute static.
  4. The attributes then gets initialized in the body file where the static attributes get initialized.

Listing 11. Generated code for static attribute intializing the default value for an attribute
                
Source File:

#ifndef CLASS1_H
#define CLASS1_H
//Begin section for file Class1.h
//TODO: Add definitions that you want preserved
//End section for file Class1.h

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
class Class1 {

    //Begin section for Class1
    //TODO: Add attributes that you want preserved
    //End section for Class1

    private:

        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
        static int attribute1[3][4];

};  //end class Class1

#endif

Body File:

#include "Class1.h" 
//Begin section for file Class1.cpp
//TODO: Add definitions that you want preserved
//End section for file Class1.cpp

int Class1::attribute1[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};


Adding customized ifndef sections to the C++ files

Rational Software Architect provides you with the flexibility to add more user regions. For example, you can add more #ifndef sections in the code by providing a tab for this to be added to the code. You can do this by going to the Windows Preferences tab, as shown in Figure 11.


Figure 11. Example for customizing ifndef sections in C++
Preferences window with two frames

The related generated code is shown in Listing 12.


Listing 12. Generated code for customizing an ifndef section
                
//the customized ifndef section added
#ifndef OLD_CPP 
using namespace KernelServices; 
using namespace SystemServices; 
#endif 



#include "Class1.h" 
//Begin section for file Class1.cpp
//TODO: Add definitions that you want preserved
//End section for file Class1.cpp


//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool Class1::Operation1()  {
    //TODO Auto-generated method stub
    return 0;
}


What you have learned

In this article, you have learned how to do the following using features in Rational Software Architect and Rational Systems Developer:

  • Model arrays in C++ with variable dimensions
  • Model constructor, destructor, and copy constructor
  • Model the assignment operator
  • Model getters and setters
  • Model inheritance for C++
  • Model unions for C++
  • Model abstract classes in UML
  • Model default values for attributes in C++
  • Add customized ifndef sections to the C++ files

Resources

Learn

Get products and technologies

Discuss

About the authors

Vinod Varma has been a developer working on IBM Rational modeling tools for the past 3 years. He has worked on various modeling tools like Rational Rose, Rational Software Architect, and Rational System Developer.

Pratima Gangalavoi

Pratima Gangalavoi is a Systems Software Engineer working with Rational Software Architect and Rational Systems Developer at the IBM Rational Software Bangalore lab. She works on the C++ transform for those tools.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=287955
ArticleTitle=Tips and Tricks for the C++ Transformation using Rational Systems Developer or Rational Software Architect, Part 3: Constructing C++ specific models in UML
publish-date=02122008
author1-email=vinod.varma@in.ibm.com
author1-email-cc=clarkega@us.ibm.com
author2-email=pratima.g@in.ibm.com
author2-email-cc=clarkega@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers