C++物件導向其實是一層一層的,namespace是一個大集合(也就是一個大物件拉),他底下的其他東西(class,struct,function)都可以互相包來包去,並構成一個物件,而您可以根據C++的語法使用他們來完成您的程式
這篇先不講這個,這篇主要是說在windows程式下您要怎樣來利用IDE(就是Visual Studio啦)幫你研究這種階層的關係
廢話不多說,直接進入正題
有寫過Windows下的視窗軟體的人都知道,當您有一個元件,例如Panel,假設它叫Panel1,它是一個指標,您要查他的屬性或者是命令(例如repaint()),您只要使用”->”它就會有提示屬性出來,要是您有一個自創物件,假設是class A{};您宣告一個A
a;,您要查他指令只需在a後面”.”,它就會有提示變數或是函數給您選,這功能十分方便,我打算用這個功能來讓您更了解物件導向的關係
物件導向其實十分複雜,但是當你剛入門時,通常是不會碰到AOOP(高等物件導向),所以您在看c++
primer plus 6時,其實後面都可以跳過,因為它算是工具書,什麼都寫,所以像是tempalte(模板),繼承,虛函數,或是奇奇怪怪的建構元,您都可以先跳過(但是不代表您以後不用學,您進業界就知道,這些東西都是用來兜出您的軟體系統的基本知識,您只要看別人應用過了,你會發現他其實很好用,然後您也會自己下去用它…),這通常要進一些比較有技術底子的公司才看的到,不然您說我碩士畢業後,會這些嗎,真的是想太多了,我那時候要是沒有課程壓力,我還不想學咧
剛入門您只要知道function,class,struct,#define,和學校教的那些基本變數型態便可以了,其他都是當您對物件導向比較通時,並且有寫過幾個小程式時,在看您接的案子需要再做學習(通常你摸到中大型案子=全學拉),你有東西不會用,卡在一個小地方或小技巧,您寫的code會很長,寫的時間會很久,總之壞處很多
這裡是重點
很多啦,都是例子,您不懂可以把程式碼貼到程式裡跑跑看,如您真懂0.0,大概看不懂的地方就可以了,其實很快拉
物件導向他的規則是:
1. 一層接一層,上層看不到下層的東西,外層看不到內層,在下層可以看到上層的東西,在內層可以看到外層前面的東西
2. 當您在該層宣告一個變數或定義,該變數或定義在這層離開後便看不到了(也就是網路上面人家寫的生命週期)
3. 當你在不同層宣告兩個相同名稱的變數,假設您要使用到那個變數,他會向上找最近的定義那個變數當作他找到的
4. 當您使用任何一個變數,一定要有定義,而Compiler會從您那行向上回頭找,直到找到您的定義,他才會Compiler過
這裡講的是垂直關係,下一篇會講水平關係,就是不同.o檔之間的物件導向關係
//////////////////////////////////////////////////////////////////////////////
一層接一層,上層看不到下層的東西,外層看不到內層,在下層可以看到上層的東西,在內層可以看到外層前面的東西
//////////////////////////////////////////////////////////////////////////////
舉個例子您就懂了,您可依照我的例子將程式碼按照順序寫進寫進程式中,其中main_指的是您撰寫的那個函式,可以是一個buttonclick,又或者是一個執行中的函式,總之您將它貼到程式碼按編譯就對了
1.
上層看不到下層的東西
int a;
Void abc(int b)
{
++a;
}
Void main_()
{
a
= 5;
abc(a);
}
這可以正常編譯
////////////////////////////
Void abc(int b)
{
++a;
}
int a;
Void main_()
{
a
= 5;
abc(a);
}
這裡
Compiler會說找不到變數i
註:通常會出現很多Bug,一般解Bug是由上往下解,第一個解完可能後面的錯誤會跟著消失,但如果您從其他地方開始解呢,你可能永遠解不到正確的Bug(相信我)
///////////////////////////
int a;
Void main_()
{
a
= 5;
abc(a);
}
Void abc(int b)
{
++a;
}
Compiler會說找不到函式abc
///////////////////////////
有沒有看到當順序錯時,要是您不符合這種通用的Compiler編譯規則,就會跳出錯誤訊息,所以在寫程式前必須了解這種先後關係
除了第一個會編譯過,其實您還有其他種解法,
您可以使用extern關鍵字來告知Compiler這個變數或函式已經在其他地方宣告過,這樣編譯也會過
extern int a;
extern Void abc(int b);
Void main_()
{
a
= 5;
abc(a);
}
int a;
Void abc(int b)
{
++a;
}
註:這裡只是弄清楚關係,其實您將定義寫到頭檔一樣是這個問題,可以這樣解,這裡就不示範,如何寫(因為這很基本,您不會代表C沒學好)
///////////////////////
2.
外層看不到內層的東西,何況是順序錯誤
Void main_()
{
Int
a = 5;
For(int I =0;i<10;i++)
{
++a;
}
}
這裡Compiler會過,原因當您使用a這個變數進行任何動作,您在他for迴圈外(上方)宣告了,因此他回頭找有找到定義
/////////////////////////////
Void main_()
{
a
= 5;
For(int I =0;i<10;i++)
{
int
a;
}
}
這裡Compiler會說編譯器沒有找到a
原因a是在for迴圈裡宣告的,你a=5上面並沒有看到任何定義
/////////////////////////////
Void main_()
{
For(int I =0;i<10;i++)
{
int
a;
}
a++;
}
這裡Compiler一樣會說a沒有定義,原因是a是在for迴圈裡宣告的,他生命週期只有在for迴圈離開前(也就是說這個定義在for迴圈結束後就沒用了)
/////////////////////////////
Void main_()
{
Int a;
{
++a;
}
}
有沒有看過這樣寫,其實這樣編譯器也會過,也就是{}是下一層,所以您要是像下面這樣寫的化
Void main_()
{
{
Int
a;
}
++a;
}
一樣Compiler會出現a沒有定義錯誤,原因a這個定義在{}離開後就沒用了
再舉個比較特殊的例子
Void main_()
{
for(int I =0;i<10;i++)
{
Int
a;
}
for(int I
=0;i<10;i++)
{
A++;
}
}
這樣一樣Compiler會出現a沒有定義錯誤,都是之前那個原因
//////////////////////////////////
變數可以這樣搞
您確定class或struct不能這樣做嗎(這很重要喔,這會打通您對學校教的C++以偏概全的錯誤概念,因為您在學校應該也跟我一樣,class或struct只能放在頭檔或是函式外宣告吧)
void main_()
{
struct
aaa
{
int
a;
};
aaa abc;
}
您可以試試這樣,您會發現Compiler會過,但您會說這對您有什麼好處咧,這在模組化設計時很常用在函式裡宣告結構使用,這裡您只要知道他是對的就可以了
//////////////////////////
void main_()
{
{
struct aaa
{
int a;
};
}
aaa abc;
}
老問題這Compiler也會說您找不到aaa定義,這要慢慢理解,class一樣這個道理
///////////////////////////////
變數可以在函式內宣告,函式可以嗎(也就是區域函式),就我試的狀況是不行,但是可以宣告在struct裡面
void main_()
{
struct
aaa
{
int
a;
void
abcc(){++a;}
};
aaa abc;
abc.abcc();
}
這樣可以
//////////////////////////////////
void main_()
{
void abc(){}
abc();
}
這樣會錯誤,說您區域函式定義不合法
//////////////////////////////////
void main_()
{
extern void abc();
abc();
}
void abc()
{
int a = 0;
++a;
}
這樣就可以了,但是要是下面狀況咧?
void bcd()
{
int
b = 0;
abc();
++b;
}
void main_()
{
extern
void abc();
abc();
bcd();
}
void abc()
{
int
a = 0;
++a;
}
這樣bcd裡面的abc會找不到定義,有沒有很神奇,要怎樣改
void bcd()
{
extern
void abc();
int
b = 0;
abc();
++b;
}
void main_()
{
extern
void abc();
abc();
bcd();
}
void abc()
{
int
a = 0;
++a;
}
您看,這樣是不是就過了
註:要注意喔,Compiler是很死的,在前面或上層沒看到宣告或者是extern的方式表示已經宣告,就會編譯不過,一層一層的向上層或向外層找定義,找不到就去頭檔找,要是都沒有,就會找不到識別項:D
再來給您看生命週期奧妙的地方
void main_()
{
int
b = 1;
//1.這裡b是多少
++b;
//2.這裡b是多少
{
//3.這裡b是多少
int b = 5;
//4.這裡b是多少
++b
//5.這裡b是多少
}
//6.這裡b是多少
++b
//7.這裡b是多少
}
您可用下中斷點的方式,執行程式,去看他跳到那行後的b是多少,以幫助您了解我下面說的答案
//1.這裡b是多少
是1,因為她才剛宣告
//2.這裡b是多少
是2,因為++b給他加一了
//3.這裡b是多少
還是2,因為他找到的變數是外層的那個,所以當然得到是他的值
//4.這裡b是多少
他找到的定義是內層的b,我重新宣告為5,所以b的值是5
//5.這裡b是多少
他找到的定義是內層的b,又加一,所以是6
//6.這裡b是多少
由於他回到外層,看不到內層的宣告,因此他重新找到外層的b,所以是2
//7.這裡b是多少
就外層的繼續加一,所以是3
搞懂這個有助於您階層的概念
///////////////////////////
假設兩個頭檔,一個使用前置宣告,一個正常宣告
a.h
class aaa
{
Int
abc;
};
很多例子吧0.0,不難,就我知道的就那五項規則,但要搞懂您基本上要寫很多程式,光嘴砲、看文章讀懂或者是冥想是沒意義的,請多加實作,
當然實作要一個主題,這種事通常要接案子或者是研究生才摸得道的,所以為什麼碩士投資報酬率很高,跟這點有很大關係,當然前提是您有題目時您也要認真寫code,不然是沒用的(當然出社會一樣啦,但是出社會要懂得亙多,像我做AOI要涉略機械,光學,電子學,軟體(但主要還是在寫軟體拉,不過其他的也要消化吸收(有空或有機會時,是不致於要詳細研究,但是要略懂)))
生命週期這個東西,網路上好像叫它叫做scope
http://openhome.cc/Gossip/CppGossip/Scope.html