基本上一個程式會Focus在一個主題上,以Word來說,他是文書處理軟體,那它主要目的就是輸入文字及排版,做出來的可以對文字及圖片編輯及排版,而基本上同個領域都有相似的設計方式,可以看到每個文書軟體,哪個不是一張白布,一個游標,可以輸入文字的,
當然會有一些不同設計,根據每個人的不同想法,但是基於使用上,Focus的設計會根據要設計的軟體,經由時間的累積,逐漸產生很固定的程式撰寫方法,講個廢話,有人有看過網頁軟體有提供不一樣的瀏覽畫面嗎,頂多框架不同,操作不同,但是主要功能是瀏覽網頁,他瀏覽網頁那塊的設計基本上是固定的,一家網頁提出個頁籤功能,其他廠商過一陣子覺得這個功能實用,以寫得出來的前提下,過兩天就生出類似的頁籤管理了
更實際的例子,古早算1加到n可能是用for迴圈加的,但是當有人發明了梯形公式,這個東西足夠好,當大家都會時,未來算1加到n,基本上都是用梯形公式
一個領域的軟體也是經由很多工程師一直演化發展出來的,其實我們就一個初入該領域的人,是不可能什麼東西都自己想的,原則上是靠臨摹,講難聽一點就是研究完後抄襲
所以呢,我們原則上還是必須要到一些有技術性底子的公司,在經由維護他的案子,順便學習他的案子的所有一切,了解他的優缺點後,才是我們提出改進,並做出屬於我們自己的東西
總之就是不可能靠自己憑空想,儘管花了10多年自我研究,就生出很有價值的東西,
所以呢,還是要想辦法得到門票去一些有技術底子的公司取得有用的謀生能力,
後面要講的是AOI他的程式基本框架,當然也不可能是我發明的,我也是近公司才開始學習的,
進入正題
AOI就是所謂的光學檢測,他其實很雜,牽涉到機構,光學,電子,軟體,那一個人怎麼會所有領域,其實去上班就知道了,寫軟體的就知道這四個領域相關常識,其實要做時,軟體外的就發包出去請機構商做,光源買現成的…之類的,我們還是主要Force在軟體,
AOI做出來的東西,原則上要搭配自動化設備,做到一台機器並且有檢出功能才算是完整
基本上牽涉到客戶檢測的產品,產品基本上是多樣性的,假設檢測一個主機板,每個公司的主機板長的都不一樣,甚至同一家公司會有多款的主機板,那我們要賣給一個客戶,我們的軟體就必須可以編輯檢測功能,
當然有些小型檢測軟體,他只是Force在一個檢測的項目,不過那種案子對AOI來講,比較接近練功用
我們工作不外乎就是賺錢學知識,所以小型檢測軟體這裡只是稍微帶過,反正小型的檢測軟體就是一個自動化流程,我們可以做基本編輯,並且提供一個主題的檢測功能,只要能達到檢測功能,並且讓他用自動化連續跑,就設計完了,不太需要太複雜或太難的設計
但是當作到中大型的,寫軟體非常像蓋一個工廠,
假設要控制打光的光源開關,我們就要做一個光源模組控制光源,
假設要取像,就必須寫一個取像模組來得到影像
假設要控制IO,當然就是要能控制IO存取的模組,
總之一間公司是很多部門的結合,那大型軟體,就是很多模組的集合,
想想一間公司的人資部門,假設有固定一種管理模式,把她想成是一個模組,那要是公司想要用不同方式管理人資,就把這個人資部門fire掉,在另外找一批人成立一個人資部門,也就是換模組拉,以軟體為例,電源控制器很多款,那我一套大型軟體,就會做一個模組接口,這個接口可以掛上控制不同電源控制器的模組,想切換只需要用ComboBox做一下選擇,就可以控制另一款電源控制器
這裡不講實現方法,不過講實際一點就是使用AOOP的Virtual來重載模組掛載,所以學校教的一些進階寫程式知識,其實不完全是那麼理論,那麼的傳統知識,其實是我們不會應用爾已,但是說實在的學起來不知道怎麼用,學的時候真的很無趣
要編這些故事其實挺麻煩的,因此我直接列舉AOI程式框架的模組:
1. 取像模組 – 沒影像要怎麼檢測
2. 參數管理模組 – 例如我要將檢驗結果儲存在檔案裡,我們不可能把路徑寫死,因此要提供參數輸入給使用者設定
3. 檢測功能的基本模組 – 用來寫檢測演算法的
4. 畫面編輯功能模組 – 例如我要檢什麼位置,就在該位置拉一個框,到時候我們就對那個框的位置採取其中一種檢測功能
5. IO模組 – 我們要判斷一個檢測產品是不是良好,必須送信號給自動化機械,請他們幫我們做動作
6. 光源模組 – 我們打光有時會調不同亮度(電壓不同拉),需要有一個模組來控制電源控制器
7. Motion模組 – 假設要掃Line Scan影像,必須控制載台移動取像,就必須完成這一個模組
8. Model模組 – 由於程式必須用編輯的方式處理,那編輯完的資訊就必須儲存起來,以便在下次打開程式時,載入相同的檢測設定,以便可以直接進行檢測
9. 噴墨模組 – 就是送字串給噴墨設備,請他們幫我們處理噴墨動作
以上是一些比較大的模組
就實際實現軟體細節的,下面列出一些細節模組:
1. 執行緒池 – 管理執行緒的,因為現在電腦有多核心,我們將不同的檢測,批次丟給多核去處理速度會比較快
2. 參數處理模組 – 例如我要存檔,必須做一個參數存檔模組,可以讓我們利用比較簡易的寫程式方式,就將參數寫入檔案或者讀出檔案
3. 背景處理用的Cmd執行緒 – 就是一個Block住的執行緒,我們下指令時他才會進行處理動作,用以將處理丟到背景去做,例如我要存圖,就指派一個執行緒去存圖,我們視窗程式就不會畫面卡住
4. Form欄位及參數對應模組 – 有了該項設計,欄位只要呼叫一個函式,就可將所有Form欄位存入結構或者是顯示在欄位上
5. 檢測結果模組 – 我們檢測完整個產品,每個地方有沒有問題必須存起來,以便到時候查看時可以將它畫到畫面上讓人家知道是瑕疵位置
6. 拉框模組 - 就是要檢測位置要用一個框表示,檢測時對該框的相對應位置進行檢測,這個框可以放大縮小或者是旋轉或增加節點或刪除(類似PhotoShop那樣)
總之講不完拉,全部提一遍其實沒太大作用就是了,一般要看過類似的案子,看上述內容才會知道我在說什麼,
想想我這裡隨便列就15項了,要一個人完成所有模組,真的不是簡單的事,更何況還要自己想出來,這是不可能的,所以還是建議必須要想辦法進去一些有底子的公司學習,接著在看我這篇文章,會比較有感覺的:D
這裡最後要提的是,每個模組又可以多個,例如光源控制器可以開多組光源控制器,相機可以取多張影像檢測,IO也可以多張IO卡,Motion控制可以控制多軸,Model也可以做繁衍,例如檢測相同的模型用一個Model,那要是兩類就必須有兩個不同教導的Model,總之什麼都可以繁衍,
但說實在的其實一般公司在做,也不是每個東西都做繁衍,可能都只是固定數目的模組,所以不需要想太複雜:總之還是必須循序漸進,不能太急,先看看小案子再來接手大案子,會對學習比較有幫助,因為案子大了其實不是那麼好研究的
2016年4月10日 星期日
Windows程式主體架構建置前的一些知識
基本上在C++ builder寫Windows程式之前,我們必須要了解windows作業系統,他其實是一個龐大的lib庫,他有非常多已經寫好的函式可以呼叫,您可以上msdn去查,例如CreateThread,您可以利用它來產生一個執行緒,在背景幫您跑工作,
當然效率就不講了(其實已經蠻快的),效率要好其實intel的IPP裡面也提供了intel自己開發的執行緒可以建立(似乎是說效率比較好)
這裡不提Intel的,總之,Windows有很多的DLL(就是Win32 DLL,其實64Bit也可以用啦,只要您作業系統是64bit的),裡面提供無數的函式可以呼叫,
在Visual C#裡面要使用這些函式,必須如下面方式
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int CreateThread(
IntPtr lpThreadAttributes,
UInt32 dwStackSize,
IntPtr lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
UInt32 lpThreadId
);
然後您就可以使用這個函式,而在C++ Builder裡面,其實大部分的函式可以直接使用(例如CreateThread),就算不能使用只要去msdn查lib和.h是啥,include進來就可以呼叫了,除了這強大的Win32函式庫,像是STL等很多東西加個對應的.h檔就可以直接使用了,此外C++ Builder本身還封裝一些函式庫,例如您要判斷檔案存不存在,只要FileExists(檔名)就可以了,說實在的挺方便的,
其實像Windows有一些基本結構,例如RECT,BITMAP,HDC...等,他也有一些對應的Class繼承,例如TRect,您可以利用他做一些的處理,而不是只是一個結構,自己還要寫函式去處理細節
總之...很多東西東西都已經實現好了,我們可以直接使用來做處理,當然要是有些功能沒有現成的函式可以處理,那麼我們就必須將底層的Win32函式兜成一個可以用的模組,來呼叫使用,例如要用RS232送字串,我們就利用CreateFile(做法要上網查,網路都有),開啟Com Port,接收或送字串,要是要網路功能,其實他有Indy的套件可以使用,但是如果要自己用Win32函式庫兜功能呢,也是可以的,總之要上網研究一下,網路上有些程式片段只要再改一下,就可以直接使用了
總之就是說有很多函式啦,上萬個,但是其實我們做案子是有分領域的,例如做網路的,那你就只要會網路那塊的函式,做系統整合的,他有一些基本的系統整合相關的函式,原則上會您那個領域的就好,並不是說要將一萬多個函式通通摸過
很多東西上網查都有,但是要兜起來能動說實在的也不太容易,要Try很久,總之就是慢慢學習了
另外就是要會使用lib和DLL,像我做系統整合的(AOI光學檢測),往往會用到一些設備的函式,這時候通常廠商舊提供lib或DLL,並給您他的.h,這時候我們就必須用動態連結DLL的方式,來讓我們可以使用他們提供的函式,又或者是使用ImportLib轉換成C++ Builder能用的Lib來使用DLL,當然這裡就不講這個,總之先提個概念就是了
我們寫一個程式,除了呼叫函式外,就是要寫一個高效能的軟體,
最基本的要知道我們電腦一些元件的速度
CPU>L1 Cache>L2 Cache>L3 Cache>Memory>硬碟>隨身碟>外部設備,
這其實計概上有寫,實際您怎麼確定CPU是最快的呢,其實我們有軟體方法可以測,
例如我寫個For迴圈,裡面就是1+到n,這時候通常只在快取和CPU上跑,您用計算時間的函示去量他的時間(clock(),方法請上網找),
而我們要測記憶體,就是使用memcpy,您就做兩個大一點的陣列,利用memcpy在for迴圈裡面做,您會發現相同指令數,他會比較久,要是您在for迴圈做檔案存取,那又會更久了
下面是例子:
CPU&Cache
double k = 100000000;
double n = 0;
for(double i = 0;i < k; ++i)
{
++n;
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
這裡需要561ms
Memory存取
int a[1000];
int b[1000];
long start = clock();
double k = 1000000;
double n = 0;
for(double i = 0;i < k; ++i)
{
memcpy(a,b,1000*sizeof(int));
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
我for迴圈還比較少就要9.36秒
當然效率就不講了(其實已經蠻快的),效率要好其實intel的IPP裡面也提供了intel自己開發的執行緒可以建立(似乎是說效率比較好)
這裡不提Intel的,總之,Windows有很多的DLL(就是Win32 DLL,其實64Bit也可以用啦,只要您作業系統是64bit的),裡面提供無數的函式可以呼叫,
在Visual C#裡面要使用這些函式,必須如下面方式
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int CreateThread(
IntPtr lpThreadAttributes,
UInt32 dwStackSize,
IntPtr lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
UInt32 lpThreadId
);
然後您就可以使用這個函式,而在C++ Builder裡面,其實大部分的函式可以直接使用(例如CreateThread),就算不能使用只要去msdn查lib和.h是啥,include進來就可以呼叫了,除了這強大的Win32函式庫,像是STL等很多東西加個對應的.h檔就可以直接使用了,此外C++ Builder本身還封裝一些函式庫,例如您要判斷檔案存不存在,只要FileExists(檔名)就可以了,說實在的挺方便的,
其實像Windows有一些基本結構,例如RECT,BITMAP,HDC...等,他也有一些對應的Class繼承,例如TRect,您可以利用他做一些的處理,而不是只是一個結構,自己還要寫函式去處理細節
總之...很多東西東西都已經實現好了,我們可以直接使用來做處理,當然要是有些功能沒有現成的函式可以處理,那麼我們就必須將底層的Win32函式兜成一個可以用的模組,來呼叫使用,例如要用RS232送字串,我們就利用CreateFile(做法要上網查,網路都有),開啟Com Port,接收或送字串,要是要網路功能,其實他有Indy的套件可以使用,但是如果要自己用Win32函式庫兜功能呢,也是可以的,總之要上網研究一下,網路上有些程式片段只要再改一下,就可以直接使用了
總之就是說有很多函式啦,上萬個,但是其實我們做案子是有分領域的,例如做網路的,那你就只要會網路那塊的函式,做系統整合的,他有一些基本的系統整合相關的函式,原則上會您那個領域的就好,並不是說要將一萬多個函式通通摸過
很多東西上網查都有,但是要兜起來能動說實在的也不太容易,要Try很久,總之就是慢慢學習了
另外就是要會使用lib和DLL,像我做系統整合的(AOI光學檢測),往往會用到一些設備的函式,這時候通常廠商舊提供lib或DLL,並給您他的.h,這時候我們就必須用動態連結DLL的方式,來讓我們可以使用他們提供的函式,又或者是使用ImportLib轉換成C++ Builder能用的Lib來使用DLL,當然這裡就不講這個,總之先提個概念就是了
我們寫一個程式,除了呼叫函式外,就是要寫一個高效能的軟體,
最基本的要知道我們電腦一些元件的速度
CPU>L1 Cache>L2 Cache>L3 Cache>Memory>硬碟>隨身碟>外部設備,
這其實計概上有寫,實際您怎麼確定CPU是最快的呢,其實我們有軟體方法可以測,
例如我寫個For迴圈,裡面就是1+到n,這時候通常只在快取和CPU上跑,您用計算時間的函示去量他的時間(clock(),方法請上網找),
而我們要測記憶體,就是使用memcpy,您就做兩個大一點的陣列,利用memcpy在for迴圈裡面做,您會發現相同指令數,他會比較久,要是您在for迴圈做檔案存取,那又會更久了
下面是例子:
CPU&Cache
double k = 100000000;
double n = 0;
for(double i = 0;i < k; ++i)
{
++n;
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
這裡需要561ms
Memory存取
int a[1000];
int b[1000];
long start = clock();
double k = 1000000;
double n = 0;
for(double i = 0;i < k; ++i)
{
memcpy(a,b,1000*sizeof(int));
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
我for迴圈還比較少就要9.36秒
硬碟存取
FILE* file_ = fopen("c:\\a.txt","w");
long start = clock();
double k = 50000;
double n = 0;
for(double i = 0;i < k * 1000; ++i)
{
fprintf(file_, "%d", i);
}
long end = clock();
fclose(file_);
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
由於跟記憶體複製比,所以複製長度1000要做1000次,所以我乘上1000
這要20秒
外部設備(就更久,其實我知道的就只有網路和RS232,總之比較久就是了)
當然硬碟還有SSD(固態硬碟)和一般硬碟,誰比較快,您就用windows複製大型檔案看看就知道了,就是從SSD複製到SSD,硬碟複製到硬碟,
總之,假設是一個指令,越是低端的設備會越慢,這個知識牽扯到我們寫程式效率的問題,假設在for迴圈裡面存取多次低端設備,會慢很多,通常假設沒必要,for迴圈內是不處理硬碟存取的,當然這種事情很少發生,
還有一種東西也是比較慢的,也就是GDI+指令
GDI+是圖形設備介面,他的指令丟在for迴圈裡面跑也很慢,不只是GDI+指令,VCL的屬性設定或讀取也是
long start = clock();
double k = 50000;
double n = 0;
for(double i = 0;i < k * 1000; ++i)
{
fprintf(file_, "%d", i);
}
long end = clock();
fclose(file_);
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
由於跟記憶體複製比,所以複製長度1000要做1000次,所以我乘上1000
這要20秒
外部設備(就更久,其實我知道的就只有網路和RS232,總之比較久就是了)
當然硬碟還有SSD(固態硬碟)和一般硬碟,誰比較快,您就用windows複製大型檔案看看就知道了,就是從SSD複製到SSD,硬碟複製到硬碟,
總之,假設是一個指令,越是低端的設備會越慢,這個知識牽扯到我們寫程式效率的問題,假設在for迴圈裡面存取多次低端設備,會慢很多,通常假設沒必要,for迴圈內是不處理硬碟存取的,當然這種事情很少發生,
還有一種東西也是比較慢的,也就是GDI+指令
GDI+是圖形設備介面,他的指令丟在for迴圈裡面跑也很慢,不只是GDI+指令,VCL的屬性設定或讀取也是
例如:
long start = clock();
double k = 10000;
int n = 0;
for(int i = 0;i < k; ++i)
{
n += i % 1000;
//Height = i % 1000;
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
這只要0秒
long start = clock();
double k = 10000;
int n = 0;
for(int i = 0;i < k; ++i)
{
//n += i % 1000;
Height = i % 1000; // 設定Form的高,由於設超過螢幕解析度,他會pass調指令,所以這裡%1000,保證他可以下10000次設定VCL元件的指令
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
您會發現只設定Form的高10000次要3.3秒
我們必須知道一些基本的知識,不然是不能寫出高效能的程式的,這邊只是稍微提到,並不深入(其實我也沒全部了解),總之,通常當您的處理太慢時,就必須要做profile(時間分析),看把哪裡mark掉會比較快,再想辦法改寫,使的功能正常外,效能又比較高
當然有時候會為了節省程式碼,一次執行很多多餘的設定畫面VCL物件的指令,這又是另一個問題了,這關於寫Code的速度,以及管理上的方便,有時必須這麼做
但是在實現功能時,通常要注意上面舉的例子的問題,這跟設定畫面VCL物件無關
再來一般近代的程式,要是所有運算都在主執行處理,畫面會卡住,甚至點個幾次就停止回應了,所以其實一個不會當掉的程式,必須把運算量大的都丟到背景執行緒做,C++ Builder有提供TThread,而如果您不用這個就必須使用CreateThread來建立執行緒,當然Win32最近好像又多了ThreadPool及Command Thread這有空可以研究一下,總之運算量大的都要丟到背景就是了
而Windows程式有一個Windows訊息傳遞的寫法必須要會,當您丟到背景去處理運算後,處理結果要秀出到畫面,必須呼叫主執行緒跑(背景執行緒不能動到跟UI有關的東西),這裡不講這個,總之這也是必須要會的,
最後就是Wndproc是處理Form的消息的地方,當您送一個訊息給Form,他會被Wndproc所處理,這裡的寫法很重要,後面有時間會提到這裡,這裡只是簡單寫一下而已
這裡會附上面的例子,您可以用C++ Builder打開測試看看
https://drive.google.com/open?id=0B6u5oifJv3EKOWFGdHZEdDl1cms
long start = clock();
double k = 10000;
int n = 0;
for(int i = 0;i < k; ++i)
{
n += i % 1000;
//Height = i % 1000;
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
這只要0秒
long start = clock();
double k = 10000;
int n = 0;
for(int i = 0;i < k; ++i)
{
//n += i % 1000;
Height = i % 1000; // 設定Form的高,由於設超過螢幕解析度,他會pass調指令,所以這裡%1000,保證他可以下10000次設定VCL元件的指令
}
long end = clock();
double time_ = (end - start) / CLOCKS_PER_SEC;
ShowMessage(time_);
您會發現只設定Form的高10000次要3.3秒
我們必須知道一些基本的知識,不然是不能寫出高效能的程式的,這邊只是稍微提到,並不深入(其實我也沒全部了解),總之,通常當您的處理太慢時,就必須要做profile(時間分析),看把哪裡mark掉會比較快,再想辦法改寫,使的功能正常外,效能又比較高
當然有時候會為了節省程式碼,一次執行很多多餘的設定畫面VCL物件的指令,這又是另一個問題了,這關於寫Code的速度,以及管理上的方便,有時必須這麼做
但是在實現功能時,通常要注意上面舉的例子的問題,這跟設定畫面VCL物件無關
再來一般近代的程式,要是所有運算都在主執行處理,畫面會卡住,甚至點個幾次就停止回應了,所以其實一個不會當掉的程式,必須把運算量大的都丟到背景執行緒做,C++ Builder有提供TThread,而如果您不用這個就必須使用CreateThread來建立執行緒,當然Win32最近好像又多了ThreadPool及Command Thread這有空可以研究一下,總之運算量大的都要丟到背景就是了
而Windows程式有一個Windows訊息傳遞的寫法必須要會,當您丟到背景去處理運算後,處理結果要秀出到畫面,必須呼叫主執行緒跑(背景執行緒不能動到跟UI有關的東西),這裡不講這個,總之這也是必須要會的,
最後就是Wndproc是處理Form的消息的地方,當您送一個訊息給Form,他會被Wndproc所處理,這裡的寫法很重要,後面有時間會提到這裡,這裡只是簡單寫一下而已
這裡會附上面的例子,您可以用C++ Builder打開測試看看
https://drive.google.com/open?id=0B6u5oifJv3EKOWFGdHZEdDl1cms
C++class間的繼承關係研究方法
大概是上面網頁所寫的
基本上我們在做繼承時,通常只會繼承一次,避免程式碼會太複雜,
繼承太多層反而會使得您維護程式變得更困難,例如您寫了很多個class都有函式叫做abc(),結果您要用繼承的方式將很多class整合成一個class,就會發生abc()衝突,
要處理好幾層您必須每一層都仔細檢查及規劃,就一般在上班而言,一個案子通常會有時間壓力,不太可能會有時間去玩這種繼承好幾次的東西(除非您做的超級大型(像是C++
builder),但通常這種大型的東西,不是一個人能維護的)
一般就是做一個通用的class,將他放在基底,
然後您要使用時,就將它繼承出來,利用virtual來改寫操作這裡就還不講這個,這裡主要就是教您如何研究這種基底關係,
其實就如上面網頁寫的,繼承基本上就只是那樣子
但是發文不附圖,沒圖沒真相,沒看到實際的東西,您怎麼確定人家寫的是正確的
其實很簡單
您要研究這種關係,就寫兩個class A,class B
如下:
class A{
public:
A(){};
~A(){};
int a;
protected:
int b;
private:
int c;
};
class B : public A
{public:
B(){
};
~B(){};
protected:
int d;
private:
};
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
B b;
b.
}
這是一個最簡單的繼承關係,一般現在windows的IDE都會有提示功能,
如上我是將class B繼承class A,您在主程式片段就宣告個class B,然後輸入B.(如果是指標就是B->),他就會列出您可以存取的變數
我class A裡面只有放int a在public,所以您要在class外直接存取變數,您看到只有a可以選擇
那假設您要在class B裡面的成員,直接使用變數,您可以使用this->(this就是指自己本身),看有誰可以看的到
但是通常案子一寫大,有時候include太多東西,或者是太多行,C++builder有時候就不會跳出這種提示出來,所以研究完還是需要記一下
如上面的圖,您可將class B : private A,或者class B : protected A,並用上面的方法,看他的成員是否可以存取,或者是說在哪裡可以存取,並且編譯看看是否可以使用,用這種方法可以研究繼承的關係
通常假設很趕時,有時候您要使用成員看不到,您就將該成員丟到public底下,基本上是可以直接使用的,不然其實挺麻煩的,您還要像書上特別多寫一個函式,int a_get(){return a;},來取得該變數的值,或者是取得成員的指標,如果您要設定的話還要寫a_set(int value),通常除非我時間太多,或者公司有硬性規定或者已經寫好了,不然我就會向我說的將成員丟到public,就直接使用了,
多一個函式存取變數要多4行,要是您有10個變數要存取,不就要多寫40行,案子一大每個地方都這樣管理,其實一個人做實在是有點太累了,當然如果要做程式碼管理的話,還是必須乖乖的寫那些東西拉,不過如果沒上級特殊要求,我通常是會這樣處理,因為多一個函數轉換不會帶給您寫code有比較大的好處,反而會讓您的案子進展比較慢(因為要寫很多行)
當然要是您功能都開發完了,您要做程式碼管理,我是認為OK的,
但是要是您這只是小案子,其實過個幾天您就換案子維護了,做這種多餘的事其實很無聊的,就算是大案子是我的話,我通常也是先丟pullic寫好程式後,再看看要不要封裝成上面講的那樣寫法(不然寫錯了要改好幾次)
:D當然,寫Code是為了賺錢,所以案子越快完成越好,您要做任何一項動作時,除非這個動作帶給您什麼好處,例如寫Code比較快啦,修改程式碼比較有架構啦,這樣根據這個好處,才會對程式碼做有好處的動作,
這很像您上班時,公司要您打很多報告(為了管理),假設您主要工作內容是修電腦,你把報告打完或者是做的很棒,您電腦會修得比較多台嗎,
假設修一台電腦可以賺1000塊,然後您一直修可以修10台,就賺了一萬塊
要是您加上打報告時間,說不定只完成5台,您就少賺了5000塊了,
不然乾脆就裝5台,您還有時間去喝杯咖啡,或者是下午茶,總之做任何動作通常要帶來一定的好處,這好處指不是人家賦予的(例如請您順便打報告付您2萬塊)
而是實際會對您的工作效率實質上的提升,
一般還在學習時,做太多的東西做管理,您會學得慢很多(當然要是您是學管理就另外講了)
總之,這文章只是要教您如何來研究這種繼承的關係而已,其他閒談就自己判斷了,繼承用法網路上其實都已經有寫了,我這邊再打一次其實沒有太大的意義
訂閱:
文章 (Atom)