更新於 2023/10/17閱讀時間約 6 分鐘

實戰系列『影像處理軟體設計』- [10] 物件導向方法:實作模型(上)

終於完成物件導向的設計,包括用於指導撰寫程式的「類別模型」和「動態模型」。

以物件導向的方式進行設計,只是進攻的前奏,撰寫程式才是最終的目標。

雖然物件導向的理論、方法、技巧經過多年的發展後,業界已經形成基本統一的認知,但並未出現一種統一的「物件導向程式語言」。


一、程式語言的差異性

每種語言都會根據自己的需求、特徵,選擇支援或不支援物件導向,或者只支援部份物件導向的特性。

各種語言對物件導向支援的程度和方式,導致將其設計轉換為程式碼時,還需要做一次翻譯或轉換的過程。

因此,若想充分應用物件導向,除了掌握物件導向的概念、方法、技巧外,還得要精通程式語言與物件導向相關的特性。

本系列以 C/C++ 為主要程式語言,並詳細描述它們與物件導向相關的特性;在 GUI 的設計上,我們會採用 C# 及 Python 來說明。

這邊只是先擷取出 C++ 跟物件導向相關的資料,後續我們會再參考「API Design for C++」一書來了解更多的細節。


二、C++

C++是第一個廣泛流行的物件導向程式語言,至今依然佔據程式語言榜單的前幾名。

儘管 C++ 促進了物件導向程式設計的發展,但它的複雜性也伴隨著較大的爭議;尤其是與物件導向相關的特性,光是各式各樣的術語,就能把剛入門的程式開發者搞得頭昏眼花。

尤其 C++ 相容於 C 語言的特性,導致在程式中,一不留神就會出現「物件導向」和「程序導向」風格混雜的情況。

正因為 C++ 這種特性,當採用 C++ 進行物件導向程式設計時,就需要花費更多的時間和精力,以便瞭解 C++ 物件導向的特型。


三、類別

C++ 類別透過關鍵字 class  來標示。

類別的定義包含兩部分:類別標頭 (header, .h),由 class 和後面的類別名稱組成;類別實作(source, .cpp ),由一對大括弧包圍起來,裡面包含屬性和方法的宣告。

例如:

//NImage.h

#ifndef _NIMAGE_H
#define _NIMAGE_H

#include <windows.h>

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)

class NImage
{
private:
HBITMAP hBitmap;
LPBYTE lpBits;

int nWidth;
int nHeight;
int nBitCount;
int nBytesPerLine;
int nBytesPerPixel;
int nNumColors;
int nSize;

HDC hMemDC;

public:
NImage();
~NImage();
public:

// Overrides
virtual BOOL BitBlt(HDC,int,int,int,int,int,int,DWORD);
virtual BOOL MaskBlt(HDC,int,int,HBITMAP,DWORD);
virtual HDC GetDC();
virtual void ReleaseDC();

void Create(int Width,int Height,int Bits,DWORD dwFlags=0);
BOOL IsNull();
void Destroy();

int GetWidth();
int GetHeight();
int GetBPP();
int GetPitch();
int GetMaxColorTableEntries();

BYTE* GetPixelAddress(int x,int y);
COLORREF GetPixel(int x,int y );
void GetColorTable(int m, int n, RGBQUAD* ColorTab);
void SetColorTable(int m, int n, RGBQUAD* ColorTab);

BOOL LoadBMP(char* filename);
BOOL SaveBMP(char* filename);

HBITMAP* GetBitmap();

};

#endif //!_NIMAGE_H

在 C++ 中,宣告和定義是分開的,上述程式碼只是 NImage 類別的宣告,其方法需要在定義檔(source, .cpp)實作。

例如:

//NImage.cpp

#include <stdio.h>
#include "NImage.h"

NImage::NImage()
{
hBitmap=NULL;
hMemDC=NULL;
}

NImage::~NImage()
{
Destroy();
}

BOOL NImage::IsNull()
{
if (hBitmap==NULL)
return(TRUE);
else
return(FALSE);
}

void NImage::Destroy()
{
if (hBitmap!=NULL)
{
DeleteObject(hBitmap);
hBitmap=NULL;
}
}


四、存取控制

C++類別的屬性和方法,都可以指定三種存取控制方式:

  1. public: 程式的任何地方都可以存取,例如類別本身、其他類別、其他函式等。
  2. protected: 對子類別就像 public 一樣,對其他程式則表現得像 private。
  3. private: 只能被該類別的成員函式和朋友類別(friend class)存取。

C++ 是分段的存取控制方式,每段的開始透過存取限定詞加上一個冒號 ( : ),直到另一個分段開始時結束,或者到類別定義結束。

一個類別允許包含多個存取控制段;如果沒有指定存取限定詞,則預設為 private。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.