DrawBlank第乙個工程實戰總結

2021-08-11 14:19:59 字數 3983 閱讀 6091

最近在通過乙個小的畫圖軟體專案去學習怎麼在實際專案中設計各個類以及怎麼抽象介面。

以前看各種庫以及別人的工程**總是從他們用的各種設計模式去理解,但是一直都沒有能夠理解為什麼要這麼設計要這樣做。直到自己去寫的時候才發現很多很多自己理解的還太少。只能日積月累吧。

切記三句話:

組合優於繼承

面向介面程式設計,不是面向實現程式設計

封裝變換

#ifndef _figure_h_

#define _figure_h_

#include

#include

#include "blackboard.h"

//figure類是所有圖形類的基類 定義了公共的介面以及圖形的公共資料型別的結構體

class figure

; std::string prompt;

//在blackboard &board 上展示當前圖形的介面

virtual

void displayfigure(blackboard &board) {}

//獲得當前圖形的提示字串的介面

virtual

std::string getdescription()

//獲得引數陣列的長度的介面

virtual

int getargsize()

//根據傳入的i獲得引數陣列對應第i個引數的引用

virtual parameter& getargdata(int i)

//根據傳入的i獲得引數陣列對應引數的描述字串

virtual

std::string getargdescription(int i)

};class circle :public figure

virtual

void displayfigure(blackboard &board)

virtual

std::string getdescription()

virtual

int getargsize()

virtual parameter& getargdata(int i)

virtual

std::string getargdescription(int i)

};class line :public figure

virtual

void displayfigure(blackboard &board)

virtual

std::string getdescription()

virtual

int getargsize()

virtual parameter& getargdata(int i)

virtual

std::string getargdescription(int i)

};class rect :public figure

virtual

void displayfigure(blackboard &board)

virtual

std::string getdescription()

virtual

int getargsize()

virtual parameter& getargdata(int i)

virtual

std::string getargdescription(int i)

};class ********: public figure

virtual

void displayfigure(blackboard &board)

virtual

std::string getdescription()

virtual

int getargsize()

virtual parameter& getargdata(int i)

virtual

std::string getargdescription(int i)

};#endif // #ifndef _figure_h_

我的想法是構建乙個所有圖形的基類,這個基類通過虛函式的方式給出了所有圖形的公共介面。

我所面對的問題就是,設計這個類的時候將太多的資訊放在了圖形這個類當中,雖然可以通過各個不同的派生類可以很好的得到具體的實現但是全部都冗雜在圖形這個類顯得**過於複雜,下一步需要考慮將功能拆分,設定新的類去管理圖形的提示資訊等等。

1.首先是switch的問題:

while(-1!=input_type) 

case

1: case

2: case

3: default:

std::cout

<< "請輸入正確的值。";

}

這裡是根據使用者輸入的不同的input_type通過switch確定要建立的圖形物件。

如果不將每個case加上化括弧,就會出現以下的錯誤:

問題就是:語句可能沒有被執行到(執行其他case了)導致變數沒有初始化而導致接下來的錯誤,所以需要把變數放到switch前面宣告初始化,如果不想把初始化放在switch前面,還有乙個解決方法,在swith中定義內部變數加括號,就可以了。

2.對於乙個類靜態成員函式的使用:

首先下面是圖形管理的類的定義:

class figuremanager

// figuremanager類析構函式

virtual ~figuremanager()

// figuremanager類介面.

public:

void input(std::istream &is);

void display(blackboard &board);

}; // class figuremanager類定義結束.

這個類的設計有個特點:採用乙個public靜態方法handle() 去得到乙個靜態圖形管理的物件manager

這個manager對於這個類是共享的獨乙份的,所以通過類名就直接可以得到這個物件:figuremanager::handle()。因為是靜態成員函式,所以不用任何的例項物件就可以呼叫這個函式,這是屬於類的方法。

//這裡設定了乙個新增影象到figuremanager 例項物件的figurelist容器當中的函式

void addfigure(figure* figure)

figuremanager::handle().figurelist.push_back(figure);

}

對於類的大小可以看這篇文章:

1.為類的非靜態成員資料的型別大小之和.

2.有編譯器額外加入的成員變數的大小,用來支援語言的某些特性(如:指向虛函式的指標、虛繼承、多重繼承).

3.為了優化訪問效率,進行的邊緣調整.

4. 與類中的建構函式,析構函式以及其他的成員函式無關.

5. 私有繼承,會去繼承之前的私有成員變數麼? 會…在記憶體中仍然分配相應的空間,只是在子類中是不可見的!

6. 在做多層次的繼承類大小時某個子類的類大小總是等於父類的大小加上子類中資料成員和是否有虛函式,是否是虛繼承等因素來決定。

而類的靜態成員在編譯的時候就被分配到全域性區不屬於這個類。

3.對於sizeof()這個函式:

sizeof()這個函式求是當前這個型別所佔的位元組數。

在對乙個陣列求sizeof()的時候求的是陣列總位元組數 如果需要得到陣列的元素個數需要再除以每個元素的大小sizeof(arg)/sizeof(parameter);

最後還有許多的小細節需要注意,以後在慢慢積累吧。

Qt with OpenGL 第乙個工程

最近在系統的學習有關opengl的內容,參考的主要學習資料是joey de vries的教程在github上的中文翻譯 learnopengl cn qt5.5版本以上已經整合opengl,不需要在工程檔案 pro 中引入任何庫檔案就可以使用qt中整合的opengl。關於如何在qcreator中新增...

RTT第乙個工程

第乙個rtt工程 1.配置工程 選擇晶元stm32f103c8 其包含該晶元的flash及sram介紹 jlink sw模式 output debug info browse info,可以直接定位函式和變數。2.修改led相關gpio。3.核對串列埠。rtconfig.h中定義串列埠終端rt co...

建立第乙個Django工程

建立第乙個django工程 django環境算是配置完成了,你可以到命令提示符下建立第乙個django應用,進入某個目錄,執行django admin.py startproject myproject來建立乙個工程 這時在myproject目錄下有乙個資料夾myproject和乙個manage.p...