1. 程式人生 > >C++基礎——用C++例項理解UML類圖

C++基礎——用C++例項理解UML類圖

                     

本文包括以下內容:

  • 類間存在哪幾種常見關係?
  • 它們之間的區別和聯絡是什麼?
  • 如何在程式碼中反映類間的關係?
  • 如何理解 IN/OUT mode型的引數?

類展示

class Circle{private:    double radius_;    Point center_;public:    void setRadius(double _radius);    void setCenter(Point _center);    double getArea() const;    double getCircumfrence() const;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

這裡寫圖片描述

基本概念及術語

可見性(visibility)

  • ‘+’ public
  • ‘-’ private
  • ‘#’ protected

引數的方向(parameter direction)

  • ‘in’:用於輸入的引數,get the value

  • ‘out’:用於輸出的引數, set the value

  • ‘inout’:既可作為輸入又可作為輸出, get the value and set the value

這種引數形式常見於,這樣一種情況,傳遞的是一個指標變數(如果傳遞的是一個既非指標,也非引用的變數,就純做輸入(in)了),既然是指標變數,便可提領指標,修改其指向的內容,既具備提供輸入,又具有修改原值 的雙重屬性。

舉例如下:
對一個介面作如下documentation:

Prototype: ULONG GetActivationState( ULONG * pActivationState );

Parameters

Type: ULONG*Variable: pActivationStateMode: IN/OUT
  • 1
  • 2
  • 3

客戶端程式碼

ULONG activationState = 1;ULONG result = GetActivationState(&activationState);
  • 1
  • 2

既然提供的是變數的地址,便可輕易地get the value 和 set the value。 所以根據GetActivationState(ULONG*) 引數的IN/OUT狀態,推測其中的程式碼如下:

ULONG GetActivationState(){    if (*activationState == 1)      // 可讀屬性,in    {        // TODO        // 對變數值進行修改,例如,改為0        *activationState = 0;       // 可寫屬性,out    }    return *activationState;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

類成員(變數或者函式)的型別

  • 靜態成員,下劃線表示
  • 純虛擬函式,斜體

類關係

  • Assocation (knows a)
  • Dependency (uses a)
  • Composition (has a)
  • Aggregation (has a)
  • Inheritance (is a)
  • Class template

關係的多重性(multiplicity)

  • ‘0..1’, 無例項,或者1個例項
  • ‘1’,只有一個例項
  • ‘0..*’,
  • ‘1..*’

類關係

assocation(konws a)

一個物件知道另一個物件的存在,該物件持有另一個物件的指標或者引用。


這裡寫圖片描述
class X{public:    X(Y* _ptrY):ptrY_(_ptrY) {}    void setY(Y *y) { ptrY_ = y;}    void f() { ptrY_->foo();}private/public:    Y* ptrY_;       // X類持有Y的一個指標,可據此呼叫Y中的成員方法}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

dependency

當類Y與類X彼此獨立,而類Y是類X成員函式的一個引數,或者X中成員函式的一個區域性變數。


這裡寫圖片描述
class X{...    void f1(Y y) { ...; y.foo(); }    void f2(Y& y) { ...; y.foo(); }    void f3(Y* y) { ...; y->foo(); }    void f4() { ...; Y y; y.foo(); }    void f5() { Y::staticFoo();}...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Aggregation

聚類發生的場景是:一個類是另一個類的集合或者容器,但被包含的類與容器本身並不具備相同的生命期,也就是容器銷燬時,其包含的內容未必。關聯(association)與聚合(aggregation)的不同之處在於,關聯關係不存在一個明確的容器包含另外一個類。比如汽車和輪胎的關係,就是一種聚合關係,汽車包含著輪胎的集合,汽車的銷燬,輪胎仍然可以存在。


這裡寫圖片描述
class Window{public:    //...private:    vectr<Shape*> ptrShapes; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

這裡寫圖片描述

Composition

組合(composition)是聚合(Aggregation)的增強版。組合和聚合的根本不同在於類與其所持有元素的是否具有相同的生命期,要求必須相同是一種組合關係。


這裡寫圖片描述
class Circle{private:    ...    Point center_;...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

這裡寫圖片描述
class X{...Y y;        // composition, 相同的生命期,            // 如何是引用或者指標型別,則是關聯型別,是一種弱聯絡Y b[10];    // 0...10, composition}class X{    X() { a = new Y[10]; }    ~X() { delete[] a;} ...    Y *a;       // 0...10, composition,X物件析構時,必須對a進行釋放}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

繼承(泛化)

類間的繼承關係表達的是一種derived class B is a base class A


這裡寫圖片描述


這裡寫圖片描述

類模板

類模板意味著泛型類。


這裡寫圖片描述
template<class T>class X{...};X<Y> a;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

References