内容


使用 Rational Systems Developer 或 Rational Software Architect 进行 C++ 转换的提示和技巧,第 3 部分

使用 UML 对 C++ 特定模型进行建模

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用 Rational Systems Developer 或 Rational Software Architect 进行 C++ 转换的提示和技巧,第 3 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用 Rational Systems Developer 或 Rational Software Architect 进行 C++ 转换的提示和技巧,第 3 部分

敬请期待该系列的后续内容。

这篇文章将向您显示如何建模数组、联合体、抽象类,为属性建模默认值等等。它还为您提供一些关于如何利用 Rational Software Architect 特性来进一步制定由 C++ 转换产生代码的技巧。

利用维数可变的 C++ 建模数组

这个部分讨论了利用 C++ 建模数组的问题,并且它的维数可以像变量一样被指定。要创建一个类型为 a[m] 的一维数组(这里的 m 是一个已经被定义和初始化的整数变量),可以在 UML 模型中在这个数组变量 a 上运行 cpp_type 原型。接下来,将这个原型的数组维度属性设置为 [m],如图 1所示。要完成这个操作,可以按照下面这些步骤进行:

  1. 选择要被建模成为一个数组的 UML 类属性。
  2. 由于这个属性在 Project Explorer 中仍然被选择,可以切换到 Properties 视图,然后点击 Stereotypes 页签。
  3. 点击 Apply Stereotypes 按钮并选择 cpp_type 模型。
  4. 选择这个模型中具体指定的arrayDimensions属性,然后指定这个数组的维度,如图 1所示。
图 1. 为这个数组确定维度
为这个数组确定维度
为这个数组确定维度

产生的相关代码显示在列表 1中。

列表 1. 在 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

建模构造函数、分析构造函数,以及拷贝构造函数

这个部分讨论了为一个 C++ 类建模构造函数,分析构造函数,以及拷贝构造函数。要为一个叫作 Class1 的 C++ 类产生这些,可以按照一下步骤进行:

  1. 创建一个叫作 Class1 的 UML 类。
  2. 切换到 UML 的 Properties 页签到达 C++ Transformation 配置向导,然后选择 ConstructorDestructor, 以及 Copy Constructor 选项,如图 2所示。
图 2. 建模构造函数、分析构造函数,以及拷贝构造函数
建模构造函数、分析构造函数,以及拷贝构造函数
建模构造函数、分析构造函数,以及拷贝构造函数

产生的相关代码显示在列表 2中。

列表 2. 由构造函数、分析构造函数,以及拷贝构造函数产生的代码
#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

建模 Assignment Operator

这部分讨论的是为 C++ 类建模一个赋值操作符。要为 一个叫作 Class1 的 C++ 类产生任务分配器,可以按照一下这些步骤进行:

  1. 创建一个名为 Class1 的 UML 类
  2. 切换到 Transformation Configuration 向导的 Properties 页签,并选择 Assignment 选项。
图 3. 为属性建模赋值操作符
same tab with different options chosen
same tab with different options chosen

产生的相关代码显示在列表 3中。

列表 3. 生成的代码带有激活的赋值操作符
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
}

建模抽象的属性

这个部分讨论的是在 C++ 类中为一个属性建模抽象的属性。要在一个名为 Class1 的 C++ 类中为一个 C++ 属性产生这些,可以按照以下步骤进行:

  1. 创建一个名为 Class1 的 UML 类。
  2. 添加一个名称为属性1的 UML 属性,并将它的类型设定为 Integer。
  3. 然后在 Transformation Configuration 向导的 Properties 页签中选择 Getters and setters 选项。
  4. 这个转换配置为您提供了更深一层的选项,从而使这些抽象的属性 Inline 或者 By reference,通过选择Getters and setters 下转换配置中的属性来进行,如图 4所示。
图 4. 为属性建模抽象的属性
为属性建模抽象的属性
为属性建模抽象的属性

产生的相关代码显示在列表 4 (Inline) 和列表 5中 (仅供参考)。

列表 4. 产生的代码有 Getters and setters 和 Inline 选项
#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
列表 5. 产生的代码有带有 By 参数选项的 Getters and setters
#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

为 C++ 建模继承

继承在面向对象编程中是一个重要的特性,UML 为它的建模提供了方法。要建模继承,可以利用由 UML 建模面板提供的一般化关系,它是从继承类到基础类而绘制出来的。例如,仔细考虑建模一个拥有多个继承特征的模型。在图 5所示的模型中,来自常见类的 UML 类 DerivedClass1 叫作 BaseClass。

图 5. 为 C++ 建模继承特性
为 C++ 建模继承特性
为 C++ 建模继承特性

产生的相关代码显示在列表 6中。

列表 6. 为一个称作 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

C++ 转换还提供了一个构架,它可以运用在一般称作cpp_generalization的情况下。这个建模下有它自己的属性,它们可以使您为继承特性设置 access specifier,如图 6所示。

图 6. 应用这个 cpp_generalization 原型
应用这个 cpp_generalization 原型
应用这个 cpp_generalization 原型

产生的相关代码显示在列表 7中。

列表 7. 为带有 cpp_generalization 原型的 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

为 C++ 建模联合体

这部分帮助您理解如何利用 UML 来建模联合体。C++ 转换允许您通过提供一个cpp_union构件来建模,您必须首先对包含这个联合体的 UML 模型运用这个 CPP 转换文件。要建模这个联合体,可以添加一个 UML 类到这个模型,并添加这个 cpp_union 到它,如图 7所示。.

图 7. 为 C++ 建模联合体
原型标签
原型标签

这个构架包括一个叫作 isAnonymousUnion 的构架 (如图 7所示)。当您制定一个匿名的的联合体时,这个属性可以被设定为True。这个匿名联合体必须用元素嵌套,并且在这个模型的顶部并不存在。

产生的相关代码显示在列表 8中。

列表 8. 为联合体 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

利用 UML 建模的抽象类

抽象,正如您所知道的那样,是一个非常重要的 Object Oriented 概念,而且 Rational Software Architect 和 Rational System Developer 中的 C++ 转换允许您用这两种方法进行建模。第一种方法是利用 UML 模型元素, Interface。UML to C++ 转换的 UML 将它看作一个抽象类,并且产生反映相同特性的代码。例如,仔细考虑下面的模型:

  1. 创建一个拥有 Car and Trucke 类的 UML 模型。
  2. 这些类都是 工具 类型的例子。添加一个名为 Vehicle 的工具到这个 UML 模型中。
  3. 在这个建模面板中,选择 Interface Realization 并实现从类到接口的转变。
  4. 这个模型看起来应该如图 8所示。
图 8. 利用 C++ 建模接口
利用 C++ 建模接口
利用 C++ 建模接口

这个模型元素 Vehicle 的代码显示在列表 9中。尽管这些接口的定义与那些类定义十分相似,但是这些接口下面的操作通常是抽象的。您可以通过实现接口和类执行来执行这些抽象操作。在这些产生的代码中,这些类可以延伸这个接口所提供的操作。例如,在以上的模型中,这个 car 或者 truck 类可以重载 getNumberOfTyres()getVehicleNumber() 操作的默认行为,从而为他们的例子定义具体的行为。

列表 9. 为接口 Vehicle 产生的代码
#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

第二种建模抽象类模型的方法是拥有一个 UML 类(例如,Class1)。在这个类的 UML Properties 页签中,选择 Abstract 按钮从而制定这个抽象类概要,如图 9所示。

图 9. C++ 的抽象类实例
C++ 的抽象类实例
C++ 的抽象类实例

您应该在这些案例中使用抽象类,这些案例中只包含一定数量的需要在来自它的实例中被执行,然而您可以利用所有的方法都需要通过实例来实现的接口来完成,因此接口仅仅向世人表明这个对象的抽象看起来将是什么样子的。

利用 C++ 为属性建模默认值

当您在一个类中拥有一定的属性,您应该能够利用一些初始值来初始化这些属性。这不仅仅是一种您可以完成它的方法。您还可以根据后面例子的帮助来进一步理解它。首先,建模一个 拥有 Integer 类型数组属性的模型,它的维度是 [3][4]。这个属性的默认值在这个模型中已经设定,如图 10所示。

图 10. 利用 C++ 为属性创建默认值
 利用 C++ 为属性创建默认值
利用 C++ 为属性创建默认值

要建模一个模型,可以按照以下这些步骤进行:

  1. 创建一个拥有 Class1 类的 UML 模型。
  2. 添加一个 Integer 类型的属性(attribute1)到这个类中。
  3. Properties 页签中为这个属性设定默认值,如图 10所示。
  4. 在这个模型中转换配置就像一个源,可以激活 Properties 页签中的 Constructor 选项。
  5. 然后这个属性在构造函数中被初始化,如列表 10所示。
列表 10. 为初始化一个属性的默认值的构造函数而产生的代码
#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
}

第二种创建模型的方法如下所示:

  1. 创建一个拥有 Class1 类的 UML 模型。
  2. 添加一个 Integer 类型的属性 (attribute1)到这个类,并为这个属性在Properties页签上设定它的默认值,如图 10所示。
  3. 在这个属性的 Properties 页签上,选择 Static 复选框,从而确保这个属性是静态的。
  4. 这些属性然后在主体文件中被初始化,并且静态属性也会被初始化。
列表 11. 为静态属性初始化一个属性的默认值而产生的代码
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}};

添加自定义的 ifndef 部分到 C++ 文件中

Rational Software Architect 为您提供灵活性从而可以添加更多的用户区域。例如,您可以为添加到 这个代码的数据段提供一个页签,从而以代码的形式添加更多的 ifndef 部分。您可以通过操作 Windows Preferences 页签来实现它,如图 11 所示。

图 11. 在 C++ 中自定义 ifndef 部分的例子
在 C++ 中自定义 ifndef 部分的例子
在 C++ 中自定义 ifndef 部分的例子

产生的相关代码显示在列表 12中。

列表 12. 为自定义 ifndef 部分生成的代码
//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;
}

您已经学到的内容

在这篇文章中,您已经学习了如何利用 Rational Software Architect 和 Rational Systems Developer 中的特性处理下面这些操作:

  • 使用可变维度建模 C++ 中的数组
  • 建模构造函数,析构函数,以及拷贝函数
  • 建模赋值操作符
  • 建模 getter 和 setter
  • 建模 C++ 的继承
  • 建模 C++ 的联合体
  • 建模 UML 中的抽象类
  • 建模 C++ 中属性的默认值
  • 添加自定义的 ifndef 语句段到 C++ 文件中

相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=349370
ArticleTitle=使用 Rational Systems Developer 或 Rational Software Architect 进行 C++ 转换的提示和技巧,第 3 部分: 使用 UML 对 C++ 特定模型进行建模
publish-date=10242008