VC-BookExample
-
Upload
supanan-kraitana -
Category
Documents
-
view
119 -
download
4
Transcript of VC-BookExample
มหาวทยาลยเทคโนโลยมหานคร
การเขยนโปรแกรม
ส าหรบวนโดวสดวย
Visual C++
C++ Never Die
ดร.สนน ศรสข
ภาควชาวศวกรรมคอมพวเตอร
A Language for High Performance Computing
VC 6 VS 2003 VS 2005
ตวช และตวแปรแบบอางอง
ฟงกชน และตวชฟงกชน
แนวคดและหลกการเขยนโปรแกรมเชงวตถ
เจาะลกการเขยนโปรแกรมเชงเหตการณ
ประโยชนจากการเขยนโปรแกรมเชงวตถและเชงเหตการณ
สถาปตยกรรมแบบ SDI และ MDI
การใชดไวซคอนเทกในการวาดภาพกราฟก
การใช TIMER
การแบงงานโดยใช Thread
การเรงความเรวในการท างาน ดวยการเขยนโปรแกรมแบบขนาน
พลาดไมได ส าหรบ
การเข
ยนโปรแกรมย
คใหม
:
การเข
ยนโปรแกรมแ
บบขน
านส าหร
บท างานบน
คอมพ
วเตอรหน
งเครอง
ISBN
Microsoft Visual C++ นบเปนเครองมออกตวหนง ในการเขยนโปรแกรมเชงวตถ และเชงเหตการณ ทม
ประสทธภาพมาก เนองจาก C++ เปนภาษาทมความยดหยน ท างานไดรวดเรว ดงนนจงเหมาะส าหรบ
งานทซบซอน งานทมการค านวณ และตองการการท างานทรวดเรว โดยในหนงสอเลมนจะมการอธบาย
พนฐานการใชตวชและตวชฟงกชน หลกการในการเขยนโปรแกรมเชงวตถ การเขยนโปรแกรมเชงเหต
การวาดภาพกราฟกดวยดไวซคอนเทก การใช TIMER การสรางเธรด การเขยนโปรแกรมแบบขนานบน
C P U ทมหลายแกน ผเขยนจะเนนการอธบายหลกการและเหตผลในแตละหวขอ โดยมการแทรก
วธการใชงานในบางสวน ดงนนหนงสอเลมน จงเหมาะส าหรบนกพฒนาทมความเขาใจภาษา C/C++ ด
พอสมควร และตองการจะทราบรายละเอยดในระดบลกในการเขยนโปรแกรมบนวนโดวส
with Visual C++ Pro
gra
mm
ing
การเขยนโปรแกรมบน
วนโดวสดวย Visual C++
ดร.สนน ศรสข
โครงการต าราวชาการ
ภาควชาวศวกรรมคอมพวเตอร
มหาวทยาลยเทคโนโลยมหานคร
ค าอธบายหนาปก
หนาปกเปนรปสงโตสองตวหนหนาเขาหากน ทมองบางสงอยางมจดหมาย ซงมความหมาย
เชงสญลกษณดงน
ท าไมตองเปนสงโต ?
สงโตถอไดวาเปนราชาของสตวปา ซงอยในล าดบชนบนสดของสตวนกลา แขงแรง ดราย
และไมมศตรตามธรรมชาต หากเปรยบเทยบการเขยนโปรแกรมบนระบบคอมพวเตอรแลวนน ไมวา
จะเปนระบบปฏบตการวนโดวส ยนกส และลนกซ ภาษา C ถอไดวา เปนภาษาทแขงแรง มนคง ม
ประสทธภาพสง ท างานไดเรว ซงเราอาจถอไดวาภาษา C เปนราชาของภาษาในการเขยนโปรแกรม
ท าไมตองมสงโตสองตว ?
เนองจากภาษา C + + ถกพฒนามาจากภาษา C โดยมการเพมเตมความสามารถในการเขยน
โปรแกรมเชงวตถเขาไป ท าให C + + เปนภาษาทแขงแรงโดยธรรมชาตอยแลว ซงความสามารถใน
การเขยนโปรแกรมเชงวตถ มสวนชวยใหการเขยนโปรแกรมบางประเภท สามารถเขยนไดอยางม
ประสทธภาพมาก เชน เกมส และโปรแกรม Visio ซงตองคดในเชงวตถ ดงนนหากเราใหภาษา C
เปรยบไดกบสงโต ภาษา C++ จงตองเปนสงโต 2 ตว
ประวตผแตง
ผแตงจบการศกษาระดบปรญญาตรและโท จากมหาวทยาลยเทคโนโลยมหานคร และ
วศวกรรมศาสตรดษฎบณฑต จากมหาวทยาลยเทคโนโลยมหานคร ในขณะศกษาปรญญาเอก ไดไป
ท าวจย ณ ศนยวจย CVSSP มหาวทยาลยเซอรเรย ประเทศองกฤษ ซงเปนสวนหนงของวทยานพนธ
ปรญญาเอก ผลงานวจยดานการรจ าภาพใบหนา ไดรบรางวลชนะเลศในระดบสากล (มความผดพลาด
ต าสด) ในการประกวดการแขงขนการรจ าภาพใบหนา Face Verification Competition on the
XM2VTS Database ป 2003 และอลกอรทมไดรบการยอมรบในองคกรวจยและพฒนาระบบรจ าภาพ
ใบหนา h t t p : / / w w w . f a c e - r e c . o r g / ซงปจจบนผลงานวจยดานการรจ าภาพใบหนามนกวจยใน
ตางประเทศไดน าไปวจยตอยอดมากขนในแตละป ในป 2005 ชอและประวตไดรบการตพมพลงใน
Who is Who in the World และ Who is Who in Science and Engineering มผลงานวจย (วารสารและ
ประชมวชาการทงในและตางประเทศ) มากกวา 30 บทความ ปจจบนท างานต าแหนงอาจารยประจ า
ภาควชาวศวกรรมคอมพวเตอร คณะวศวกรรมศาสตร มหาวทยาลยเทคโนโลยมหานคร
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
II
III
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
การใชเครองหมายแบบฮงกาเรยน (Hungarian Notation)
การใชเครองหมายแบบฮงกาเรยนเปนการก าหนดชอตวแปร โดยทชอตวแปรสามารถบงบอก
ถงชนดขอมลของตวแปรนนๆ ได โดยปกต ชอตวแปรทตองการสรางขนมาจะน าหนาดวยตวอกษร
ตวเลกทบงบอกถงชนดขอมลของตวแปรนนๆ จากนนกจะตามดวยชอตวแปร ซงจะขนตนดวย
ตวอกษรตวใหญ เชน nTotal เปนตวแปรมชนดขอมลแบบ int ใชเกบผลรวม เครองหมายแบบฮง
กาเรยนมรปแบบดงน
ชนดขอมล เครองหมายน าหนา ตวอยาง
int n nID
char ch chMessage
float fl flCurrency
double d dSalary
unsigned u uCode
long l lMoney
BOOL b bIsDraw
WORD w wSize
DWORD dw dwError
ตวช (Pointer) p pButtonOK
ตวแปรสมาชกของคลาส m_ m_nID
สตรง sz szName
คอนโทรล wnd wndButtonName
อยางไรกตาม เราสามารถใชเครองหมายผสมกนไดเชน ตวแปรชอ Name มชนดขอมลเปน
แบบสตรง โดยใชตวช และเปนสมาชกของคลาส จะมเครองหมายน าหนาดงน m_pszName
IV
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
สญลกษณทใชในต าราเลมน
ในต าเราเลมน มการใชสญลกษณเพอเปนหมายเหตเพมเตม โดยมความหมายดงน
เปนค าแนะน า หรอค าอธบายเพมเตม
เปนสวนทควรระวง เมอเขยนโปรแกรมแลว อาจท าโปรแกรมหยดท างานได
เปนสวนทมรายละเอยดนาสนใจ อาจเปนหวใจหลกของเรองนน ซงควรมการ
จดบนทกไว
เปนขอควรคด หรอสรปแนวคดของเนอหานนๆ
เปนขอควรระวงทตองระมดระวงในการเขยนโปรแกรม เพราะอาจท าให
โปรแกรมหยดท างานหรอเกดหนวยความจ ารวไหล (Memory Leak) ได
มาโครและชนดขอมลทส าคญใน Microsoft Visual C++
การเขยนโปรแกรมดวย Visual C++ มชนดขอมลทมการนยามไวแลว เพอใหสะดวกตอการใช
งาน มาโครและชนดขอมลทส าคญมดงน
มาโคร/ชนดขอมล รายละเอยด
_tmain _tmain จะถกเปลยนเปน wmain ถามการนยาม _UNICODE ซงใชส าหรบ
โปรแกรมทตองการใชรหส Unicode
_tmain จะถกเปลยนเปน main ถาไมมการนยาม _UNICODE
V
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
มาโคร/ชนดขอมล รายละเอยด
_T(“ ”) เปนมาโครทก าหนดใหขอความมรปแบบการเกบเปนรหส Unicode ซงมขนาด
2 ไบต สามารถเกบรหสไดมากกวารหส Ascii ซงมขนาด 1 ไบต ส าหรบ Visual
C++ เปนขอบงคบวาขอความจะตองเปนรหส Unicode
_TCHAR char
CHAR typedef char CHAR;
TCHAR #ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
#endif
LPVOID typedef void *LPVOID;
LPCSTR typedef __nullterminated CONST CHAR *LPCSTR;
PCSTR typedef CONST CHAR *PCSTR;
PSTR typedef CHAR *PSTR;
PVOID typedef void *PVOID;
LPSTR typedef CHAR *LPSTR;
BYTE typedef unsigned char BYTE;
DWORD typedef unsigned long DWORD;
CALLBACK #define CALLBACK __stdcall
HANDLE typedef PVOID HANDLE;
HDC typedef HANDLE HDC;
HWND typedef HANDLE HWND;
VI
การเขยนโปรแกรมบน
วนโดวสดวย Visual C++
พมพครงท 1 เมษายน 2551
ผแตง/ออกแบบปก ดร. สนน ศรสข [email protected]
พสจนอกษร มรกต ศรสข
Microsoft Visual C++ เปนเครองหมายการคาของบรษท Microsoft Corporation และ
เครองหมายการคาอนๆ ทอางถงบรษทนนๆ
สงวนลขสทธตามพระราชบญญตลขสทธ พ.ศ. 2537
หามลอกเลยนไมวาสวนหนงสวนใดของหนงสอเลมน ไมวาในรปแบบใดๆ นอกจาก
จะไดรบอนญาตเปนลายลกษณอกษรจากผจดพมพเทานน ยกเวนโปรแกรม สามารถ
น าไปใชไดโดยไมตองไดรบอนญาต
พมพครงท 1 พ.ศ. 2551 จ านวน 500 เลม
ผลตและจดจ าหนายโดย
มหาวทยาลยเทคโนโลยมหานคร
51 ถนนเชอมสมพนธ แขวงกระทมราย เขตหนองจอก กรงเทพฯ 10530
โทรศพท 02-9883655, 02-9883666 (อตโนมต) โทรสาร 02-9883687
ISBN: 978-974-8242-37-8
VII
ค าน า
หนงสอเลมน เขยนขนจากประสบการณของผเขยนทไดพฒนาโปรแกรมและ
ท าวจย ในเรองทเกยวของกบงานดานการค านวณ เชน การประมวลผลภาพ การท า
คอมพวเตอรกราฟก และการจ าลองการท างานของระบบ เปนตน ซงลวนแลวแตตอง
อาศยการเขยนโปรแกรมดวยภาษาทมประสทธภาพสง ท างานไดเรว และมโอเวอร
เฮดต า ซงหนงในภาษาทเหมาะสมส าหรบงานค านวณคอ Visual C++
การเขยนโปรแกรมดวย Visua l C ++ นกพฒนาตองเขาใจเทคนคการเขยน
โปรแกรมหลายอยาง เชน ตวช ตวแปรอางอง ตวชฟงกชน การเขยนโปรแกรมเชง
วตถ และการเขยนโปรแกรมเชงเหตการณ เปนตน จงจะท าใหนกพฒนาสามารถ
เขยนโปรแกรมเพอใหบรรลวตถประสงคตามทตองการ
ส าหรบต าราเลมน ผเขยนไดขามสวนทเปนพนฐานการเขยนโปรแกรมดวย
ภาษาซ โดยเนนเฉพาะสวนทส าคญทตองใชในการเขยนโปรแกรมดวย Visual C++
ดงนนต าราเลมนจงเหมาะส าหรบนกพฒนาทเขาใจภาษา C/C++ อยแลว และเคย
เขยนโปรแกรมดวย Visual C++ มาบาง ผอานควรศกษาต าราเลมอนทเปนพนฐาน
การเขยนโปรแกรมประกอบดวย ซงจะชวยใหเขาใจไดมากยงขน
ผเขยนหวงเปนอยางยงวา ต าราเลมน จะเปนทงหนงสอประกอบการเรยนการ
สอน และหนงสออางองดวย หากนกพฒนาเพยรพยายามทจะศกษาการเขยน
โปรแกรมดวย Visual C++ อยางตงใจ สกวนนกพฒนาจะเหนวา Visual C++ เปน
เครองมอในการเขยนโปรแกรมทมประสทธภาพสงมาก และ Visual C++ จะไมมวน
ตายไปจากโลกของการเขยนโปรแกรมบนวนโดวส เนองจากโปรแกรมในทางการคา
(Commercial Application) สวนใหญถกเขยนขนมาโดย Visual C++ ทงสน
ดร.สนน ศรสข, เมษายน 2551
VIII
โครงสรางของหนงสอ
เนอหาทไดเขยนขนในหนงสอเลมน ส าหรบการพมพครงทหนง (F i r s t Ed i t ion ) ไดแบง
ออกเปน 8 บท โดยแตละบทจะเนนเนอหาในเชงทฤษฎและตวอยางการเขยนโปรแกรม โดยไมเนน
การใชงาน Visual C++ ดงนนผอานจะเหนความแตกตางจากหนงสอเลมอนทเปนคมอการใชงานได
อยางชดเจน อยางไรกตามควรมคมอการใชงานประกอบดวย เพอท าใหนกพฒนาเขาใจพนฐานการใช
งานดวย เนอหามรายละเอยดดงน
บทท 1 แนะน าการเขยนโปรแกรมดวยภาษา C และ C++ ตวช ตวแปรอางอง ตวชฟงกชน ตวชชนด
void* และฟงกชนแบบตางๆ
บทท 2 การเขยนโปรแกรมเชงวตถ คลาสและการใชงาน การซอนขอมล ค าสงวน this การสบทอด
การก าหนดความเปนเพอน และการท าโพลมอฟซม
บทท 3 แนวคดการเขยนโปรแกรมเชงเหตการณ ควเหตการณ ขาวสารและเหตการณ โมเดลการเขยน
โปรแกรมบนวนโดวส การจบคขาวสาร และตวอยางการจบคขาวสาร
บทท 4 สถาปตยกรรมในการเขยนโปรแกรมแบบดอกควเมนต/วว องคประกอบของสถาปตยกรรม
แบบดอกควเมนต/วว หนาทของดอกควเมนต หนาทของวว หนาทของเฟรมวนโดวส หนาทของดอก
ควเมนตเทมเพลท และการคนหาเสนทางของคอมมานด
บทท 5 การวาดหนาจอเบองตน คลาสดไวซคอนเทก การใชงานคลาส C D C โหมดในการวาด
ภาพกราฟก โหมดการแมพ การก าหนดจดเรมตนและพนทการแสดงผล และการแปลงพกด
บทท 6 การเขยนโปรแกรมโดยใช TIMER การสรางไทเมอร การตอบสนองกบขาวสารวนโดวส
WM_TIMER และตวอยางโปรแกรมนาฬกาตงเวลา
บทท 7 หลกการเธรดเบองตน ฟงกชนในการสรางเธรด การสรางเธรดคนงาน การสรางเธรดประสาน
กบผใช การท าใหเธรดท างานประสานกน และการเขยนโปรแกรมแบบเธรดใหปลอดภย
บทท 8 แนวคดการเขยนโปรแกรมแบบขนาน ท าอยางไรจงจะท าใหโปรแกรมท างานไดเรวขนบน
ซพยแบบหลายแกน สถาปตยกรรมแบบขนาน การแบงกลมของฟลนน องคประกอบในการเขยน
โปรแกรมแบบขนาน กฎของอมดาฮล และตวอยางการเขยนโปรแกรมแบบขนาน
ตวอยางหนงสอ โปรแกรมตวอยาง และการแกไขทผด ผอานสามารถเขาดไดท
http://www.cpe.mut.ac.th
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
VIII
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
IX
กตกรรมประกาศ
ผเขยนขอขอบคณ นางมรกต ศรสข ทชวยตรวจทานหนงสอและแกไขค าผด และนกศกษา
วชา การเขยนโปรแกรมเชงเหตการณ ทชวยหาทผดในหนงสอ
ขอขอบคณ ผศ.ดร. ธนวา ศรประโมง ทใหค าแนะน า การวางโครงของหนงสอ และความ
เหมาะสมของเนอหาในหนงสอเลมน
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
X
สารบญ
Part I: Basic Idea & Concept บทท 1 การเขยนโปรแกรมดวยภาษา C++ 1
1.1 แนะน าสการเขยนโปรแกรมดวยภาษา C++ 2
1.2 การเขยนโปรแกรมดวยภาษา C++ 3
1.3 C กบ C++ 4
1.4 ลกษณะเดนของภาษา C++ 5
1.5 หนวยความจ าและการใชงาน 8
1.6 ตวแปรแบบอางอง (Reference Variable) 16
1.7 การเขาถงโดยออมแบบสองตอ (Double Indirection) 18
1.8 องคประกอบการเขยนโปรแกรมดวย C++ 22
1.8.1 ฟงกชน (Function) 23
1.8.2 โปรโตไทปของฟงกชน 24
1.8.3 การเรยกใชฟงกชนและการสงคาเขาในฟงกชน 25
1.8.4 การสงพารามเตอรเขาในฟงกชนโดยใชคา (Pass by Value) 25
1.8.5 การสงพารามเตอรเขาในฟงกชนโดยใชการอางอง (Pass by Reference) 27
1.8.6 การสงพารามเตอรเขาในฟงกชนโดยใชตวช (Pass using Pointer) 29
1.8.7 การใชตวชฟงกชน (Function Pointers) 30
1.8.8 ฟงกชนอนไลน (Inline Function) 37
1.8.9 ฟงกชนโอเวอรโหลด (Overloading Function) 40
1.8.10 ตวชชนด void (void*) 41
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++ 45
2.1 หลกการเขยนโปรแกรมเชงวตถ 46
2.2 คลาสและการใชงาน 48
2.3 ฟงกชนคอนสตรคเตอรและดสตรคเตอร 56
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
XI
2.4 คอนสตรคเตอรปรยาย (Default Constructor) 59
2.5 โอเวอรโหลดคอนสตรคเตอร (Overloading Constructors) 61
2.6 การสรางวตถโดยใชตวด าเนนการ new 63
2.7 โอเปอเรเตอรโอเวอรโหลด 65
2.8 ค าสงวน this 70
2.9 สมาชกแบบสแตตก 72
2.10 ฟงกชนและคลาสเพอน (Friend Class and Function) 73
2.11 ความสมพนธระหวางคลาส (Class Relationship) 75
2.11.1 การสบทอดของคลาส (Inheritance) 76
2.11.2 อะไรบางทไมไดถกถายทอดลงสบคลาส 79
2.12 การสบทอดจากหลายทาง 88
2.13 การท าโพลมอฟซม 90
2.14 ฟงกชนเวอรชวล (Virtual Function) 93
2.15 ซเปอรคลาสแบบนามธรรม (Abstract Base Class) 96
บทท 3 การเขยนโปรแกรมเชงเหตการณดวย Visual C++ 99
3.1 แนวคดการเขยนโปรแกรมเชงเหตการณ 100
3.2 รปแบบตวจดการ (Handler Pattern) 105
3.2.1 รปแบบตวจดการไมมหว (The Headless Handlers Pattern) 107
3.2.2 สวนขยายของรปแบบตวจดการ 107
3.2.3 ควเหตการณ (Event Queue) 108
3.2.4 การท างานเชงเหตการณในมมมองระบบรบสงขาวสาร (Messaging Systems) 109
3.3 การเขยนโปรแกรมขบเคลอนดวยเหตการณเชงวตถ 110
(Object-Oriented Event Driven Programming)
3.3.1 ขาวสารและเหตการณ (Message and Event) 115
3.4 โมเดลการเขยนโปรแกรมบนวนโดวส 117
3.4.1 การเขยนโปรแกรมในแบบ Win32 และ MFC 119
3.4.2 การจบคขาวสาร (The Message Map) 129
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
XII
3.4.3 กลไกการท างานในการจบคขาวสาร 135
3.4.4 ขาวสารวนโดวสจดการอยางไร 138
3.4.5 ตวอยางการจบคขาวสารกบฟงกชน 141
บทท 4 สถาปตยกรรมในการเขยนโปรแกรมแบบดอกควเมนต/วว 149
4.1 การเขยนโปรแกรมบนวนโดวสแบบ SDI 150
4.2 ขอดของสถาปตยกรรมแบบดอกควเมนต/วว 154
4.3 องคประกอบของสถาปตยกรรมแบบดอกควเมนต/วว 155
4.3.1 หนาทของดอกควเมนต (Role of the Document) 155
4.3.2 หนาทของวว (Role of the View) 157
4.3.3 หนาทของเฟรมวนโดวส (Role of Frame Windows) 157
4.3.4 หนาทของดอกควเมนตเทมเพลท 158
4.3.5 หนาทของดอกควเมนตเทมเพลทรซอรส ID 165
4.4 การสรางดอกควเมนต/วว (Document/View Creation) 166
4.5 วตถดอกควเมนต (The Document Object) 167
4.6 วงจรชวตของโปรแกรมแบบ SDI และ MDI 174
4.7 วตถวว (The View Object) 175
4.7.1 การเขาถงขอมลในดอกควเมนตในขณะทอยทวว 180
4.7.2 ฟงกชนทสามารถโอเวอรไรดไดใน CView 182
4.7.3 การรบอนพทจากผใชผานวว 183
4.7.4 การรองขอใหอพเดทหนาจอผานวว 186
4.8 วตถเฟรมวนโดวส (The Frame Window Object) 190
4.9 การคนหาเสนทางของคอมมานด (Command Routing) 193
Part II: Displaying & Processing Tools บทท 5 การวาดภาพกราฟกดวยดไวซคอนเทก 197
5.1 การวาดหนาจอเบองตน 198
5.2 คสาสดไวซคอนเทก 201
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
XIII
5.2.1 คลาส CPaintDC 203
5.2.2 คลาส CClientDC และ CWindowDC 205
5.3 ฟงกชน OnDraw 207
5.4 การเขาถงดไวซคอนเทก 210
5.5 การใชงานคลาส CDC 211
5.5.1 การก าหนดส 211
5.5.2 การจดการพกเซล (Pixel manipulation) 212
5.5.3 การวาดเสนตรงและเสนโคง 214
5.5.4 การวาดวงรและโพลกอน 218
5.5.5 การแสดงขอความ 219
5.5.6 การก าหนดคณสมบตในการวาดโดยใช GDI 224
5.5.7 การเลอกวตถ GDI ใหกบดไวซคอนเทก 225
5.5.8 การสรางปากกา (Pen) 227
5.5.9 การใชสตอควตถ (Stock Object) 230
5.5.10 การสรางแปรงระบายส (Brush) 231
5.5.11 การสรางแปรงระบายสจากภาพบทแมท 235
5.5.12 การก าหนดแบบตวอกษร 236
5.5.12.1 การก าหนดความสงและความกวาง 238
5.5.12.2 การก าหนดความเอยงและการหมนตวอกษร 239
5.5.12.3 การก าหนดแบบตวอกษร ตวหนา ตวเอยง ขดเสนใต ขดฆา 239
5.5.12.4 การก าหนดคณภาพ ความแมนย า และชอแบบตวอกษร 240
5.6 การแกปญหาหนาจอกระพรบดวยดไวซคอนเทกหนวยความจ า 242
5.7 แอททรบวทของดไวซคอนเทก 244
5.8 โหมดในการวาดภาพกราฟก (Drawing Mode) 245
5.9 โหมดการแมพ (Mapping Mode) 248
5.9.1 วนโดวสและววพอรท (Windows and Viewports) 250
5.9.2 ฟงกชนในการแมพโหมด 251
5.9.3 การก าหนดจดเรมตนและพนทการแสดงผล 252
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
XIV
5.9.4 การแปลงพกด (Coordinate Conversion) 254
5.9.5 การดงขอมลจากอปกรณ 254
บทท 6 การก าหนดชวงเวลาการท างานของฟงกชนโดยใช TIMER 259
6.1 การเขยนโปรแกรมโดยใช TIMER 260
6.2 การสรางไทเมอร 261
6.3 การตอบสนองกบขาวสารวนโดวส WM_TIMER 266
6.4 การยกเลกการใชงานไทเมอร 270
6.5 ตวอยางโปรแกรมนาฬกาตงเวลา 272
6.5.1 ขนตอนการสราง 273
6.5.2 ไทเมอร 300
6.5.3 การก าหนดโหมดการแมพ 301
6.5.4 การค านวณของเขมนาฬกา 302
6.5.5 การตงเวลาโดยใชเมาส 303
6.5.6 การก าหนดสโปรงแสง 304
บทท 7 การเขยนโปรแกรมโดยใหเธรด 307
7.1 หลกการเธรดเบองตน 308
7.2 ฟงกชนในการสรางเธรด 314
7.3 การสรางเธรดคนงาน (Creating Worker Thread) 316
7.3.1 ตวอยางในการสรางเธรดคนงาน 318
7.4 การสรางเธรดประสานกบผใช (Creating User Interface Thread) 327
7.4.1 ตวอยางการสรางเธรดประสานกบผใช 329
7.5 การสงใหเธรดหยดท างานและกลบมาท างานใหม 340
7.6 การท าใหเธรดหยดการท างานชวขณะโดยก าหนดเวลา 340
7.7 การจบการท างานของเธรด 341
7.8 การรอใหเธรดจบการท างาน 342
7.9 การท าลายวตถของ CWinThread 343
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C
++
C
++
C+
+
XV
7.10 การตรวจสอบสถานะของเธรด 344
7.11 การท าใหเธรดท างานประสานกน (Thread Synchronization) 345
7.11.1 การประสานแบบ Critical Sections 346
7.11.2 การประสานแบบ Mutexes 348
7.11.3 การประสานแบบ Events 348
7.11.4 การประสานแบบ Semaphores 350
7.11.5 คลาส CSingleLock และ CMulitLock 351
7.11.6 ควรจะประสานจงหวะการท างานของเธรดเมอไร และใชคลาสอะไร 351
7.11.7 การเขยนโปรแกรมแบบเธรดใหปลอดภย (Thread Safe) 352
7.12 ตวอยางโปรแกรมค านวณแบบเธรด 354
บทท 8 การเขยนโปรแกรมแบบขนานโดยใชเธรดหลายตว 371
8.1 แนวคดการเขยนโปรแกรมแบบขนาน 372
8.2 เมอจ านวนแกนในซพยมากขน โปรแกรมจะท างานเรวขนตามจ านวนแกนหรอไม 374
8.3 ท าอยางไรจงจะท าใหโปรแกรมท างานไดเรวขนบนซพยแบบหลายแกน 378
8.4 สถาปตยกรรมแบบขนาน 379
8.4.1 การแบงกลมของฟลนน (Flynn's Taxonomy) 380
8.4.1.1 ค าสงเดยว ขอมลเดยว (Single Instruction Single Data-SISD) 380
8.4.1.2 ค าสงเดยว หลายขอมล (Single Instruction Multiple Data-SIMD) 381
8.4.1.3 หลายค าสง ขอมลเดยว (Multiple Instruction Single Data Stream-MISD) 382
8.4.1.4 หลายค าสง หลายขอมล (Multiple Instruction Multiple Data-MIMD) 383
8.5 แนวคดการเขยนโปรแกรมแบบขนาน 385
8.6 องคประกอบในการเขยนโปรแกรมแบบขนาน 386
8.6.1 การแบงงาน (Decomposition) 386
8.6.1.1 การแยกใหท างานขนานตามขอมล (Data Parallelism) 387
8.6.1.2 การแยกใหท างานขนานตามงาน (Task Parallelism) 388
8.6.2 กฎของอมดาฮล (Amdahl’s Law) 389
8.6.2.1 การขยายและการเรงความเรว (Scaling and Speedup) 390
การเขยนโปรแกรมบนวนโดวสดวย Visual C++
C+
+ C+
+
C+
+
C+
+
XVI
8.6.2.2 การค านวณแบบขนานบน N ตวประมวลผล 392
8.6.3 การประมวลผลแบบขนานใหปลอดภย 392
8.6.3.1 การไมยอมกนทงสองฝาย และการลอค (Mutual Exclusion and Locks) 393
8.7 ตวอยางการเขยนโปรแกรมแบบขนาน 396
8.7.1 การสรางเธรดส าหรบการค านวณแบบขนาน 396
8.7.2 โปรแกรมหาคา PI 398
8.7.3 โปรแกรมหาคานอยทสดและมากทสด 405
8.7.4 การเรยงขอมล 412
ดรรชน 429
เอกสารอางอง 438
Chapter
1 บทท
เนอหาบทท 1
การเขยนโปรแกรมดวยภาษา C++
ลกษณะเดนของภาษา C++
หนวยความจ าและการใชงาน
ตวแปรแบบอางอง
การเขาถงโดยออมแบบสองตอ
ฟงกชนและตวชฟงกชน
ฟงกชนอนไลน
ฟงกชนโอเวอรโหลด
ตวชชนด void
การใชชนดขอมล* และชนดขอมล&
Part I
การเขยนโปรแกรมดวย
C++ เบองตน
2
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ไมมศลปนคนใดในโลกนจะสามารถสรางสรรคผลงาน
ไดอยางนาอศจรรยใจ โดยไมมการลงมอท าอยางจรงจง
สนน ศรสข
1.1 แนะน าสการเขยนโปรแกรมดวยภาษา C++
จ ดประสงคของการเขยนต าราเลมน เนอหาถกเขยนขน เพอนกพฒนาโปรแกรมทมความร
ความเขาใจภาษา C อยแลว และตองการศกษาเทคนคการเขยนโปรแกรมดวยภาษา C++ ซง
ผเขยนไดเลอกใช Visual C++ เปนตวคอมไพล (Compiler) ส าหรบการพฒนาโปรแกรม
เนองจากเปนตวคอมไพลทมความสามารถสง ดงนนจงเหมาะส าหรบการเขยนโปรแกรมทตองการ
การค านวณ โปรแกรมจะถกเขยนโดยใชสถาปตยกรรมแบบ ดอกควเมนต/วว (Document/View) ซง
เปนการเขยนทคอนขางเขาใจยาก นกพฒนาตองเขาใจการเขยนโปรแกรมเชงเหตการณพรอมกบการ
เขยนโปรแกรมเชงวตถ หนาจอโปรแกรมจะมองไมเหนจนกวาจะสงใหโปรแกรมท างาน ดงนน
ในชวงการเขยนโปรแกรม นกพฒนาจะเหนแตชดค าสงเทานน ผเขยนแนะน าใหอานหนงสอท
เกยวของกบการเขยนโปรแกรมดวย Visual C++ กอน เชนการสรางไดอะลอกพนฐาน การเพม
คอนโทรล คลาสพนฐานของไมโครซอฟท (Microsoft Foundation Class-MFC) สถาปตยกรรมแบบ
ดอกควเมนต/วว เปนตน จงจะท าใหนกพฒนาสามารถอานต าราเลมนไดเขาใจ
ต าราเลมนแบงออกเปนสองสวน ดงน
สวนท 1 เปนการแนะน าการเขยนโปรแกรมดวยภาษา C++ เปรยบเทยบขอดขอเสยระหวาง
ภาษา C กบ C++ จดเดนของภาษา C++ การใชหนวยความจ า ฟงกชนในรปแบบตางๆ ของภาษา C++
ตวแปรแบบอางองและตวช ตวชฟงกชน การใชตวช void* แนวคดการเขยนโปรแกรมเชงวตถ คลาส
การซอนขอมล การสบทอด การเปลยนรป การเขยนโปรแกรมเชงเหตการณ และสถาปตยกรรม
หลงจากท าความเขาใจกบเนอหาภายในบทนแลว นกศกษาจะสามารถ
□ เขาใจหลกการเขยนโปรแกรมดวยภาษา C++
□ รบทราบหลกการในการใชหนวยความจ าอยางถกตอง
□ เลอกใชฟงกชนในรปแบบตางๆ ทเหมาะสมส าหรบแตละงานได
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
3
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
แบบดอกควเมนต/วว
สวนท 2 การวาดภาพโดยใช GDI การก าหนดโหมดการวาดภาพ การก าหนดโหมดการ
แสดงผล การใช TIMER ตวอยางการสรางโปรแกรมนาฬกา การใชเธรดแบบตางๆ การควบคม
เธรด การก าหนดจงหวะการท างานใหเธรด แนวคดการค านวณแบบขนาน และการค านวณแบบ
ขนานโดยใชเธรด พรอมตวอยางการค านวณแบบขนาน
1.2 การเขยนโปรแกรมดวยภาษา C++
C++ เปนภาษาระดบกลาง [1] ซงใชในการเขยนโปรแกรมตงแตระดบลางจนถงระดบบนได
C++ สามารถตดตอกบฮารดแวรไดโดยตรง เปนภาษาทนกเขยนโปรแกรมเขาใจไดงาย ดงนนจงเปน
ภาษาทเปนทนยมส าหรบนกพฒนาโปรแกรมทวไป ทตองการสรางโปรแกรมส าหรบงานทซบซอน
และความเรวสง ซงหลงจากท C++ ถกสรางขนโดย Bjarne Stroustrup ในป 1979 โดยใหชอวา ซ
พรอมกบคลาส (C with Classes) แตภายหลงไดเปลยนชอเปน C++ ในป 1983 เนองจากม
ความสามารถอนๆ ทไดเพมเตมขนมาในภาษา C++ การเขยนโปรแกรมเชงวตถกเปนทแพรหลาย
และไดกลายเปนมาตรฐานในการเขยนโปรแกรมส าหรบงานทซบซอน การเขยนโปรแกรมดวยภาษา
C++ สามารถเขยนไดทงแบบโพรซเจอรและแบบเชงวตถ ซงความสามารถนเปนสวนทส าคญมาก
เนองจากการเขยนโปรแกรมโดยสวนใหญจะเขยนโดยใชความสามารถทงสองแบบ
การเขยนโปรแกรมดวยภาษา C++ ไดถกก าหนดใหเปนมาตรฐานตงแตป 1998 เปน ISO/IEC
14882:1998 และมาตรฐานรนลาสดของ C++ คอ ISO/IEC 14882:2003
C++ เปนภาษาทใชในการเขยนโปรแกรมเชงวตถ ซงหมายความวาการเขยนโปรแกรมดวย
C++ จะใชหลกการเชงวตถในการท างานเปนโครงสรางหลกของโปรแกรม เนองจาก C++ ถกสราง
มาจากภาษา C โดยการน าภาษา C มาเพมเตมความสามารถทางดานการเขยนโปรแกรมเชงวตถ ท าให
นกพฒนาทคนเคยกบภาษา C อยแลว สามารถท าความเขาใจกบ C++ ไดโดยงาย ดงนนจงท าให C++
เปนทแพรหลาย และใชกนอยางมากมายทวโลก อกทง มตวคอมไพล (Compiler) ทท างานบน
ระบบปฏบตการยนกส ลนกซ และวนโดวส ซงตวคอมไพลทใชกนแพรหลายมากทสดในปจจบนก
คอไมโครซอฟท Visual C++
ความแตกตางระหวางภาษา C กบ C++ ทชดเจนทสดคอ C++ มความสามารถเพมเตมในเรอง
เชงวตถ เชน ภาษา C ใชสตรคเจอร (Structure) ในการเกบขอมล เราสามารถสรางสตรคเจอรเพอเกบ
ขอมลทตองการได เชน หากตองการเกบสเหลยม เราสามารถเขยนค าสงในภาษา C เกบขอมลลงใน
4
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
สตรคเจอรไดดงน
myRectangle.Left = 100;
myRectangle.Top = 20;
myRectangle.Right = 200;
myRectangle.Bottom = 400;
ใน C++ วตถไมไดใชเกบขอมลเพยงอยางเดยว แตสามารถท างานตามทก าหนดไดดวย ซง
หากเขยนดวย C++ เราสามารถเขยนฟงกชนไวในคลาส จากนนน ามาเรยกใชไดภายหลง เชนหาก
ตองการค านวณหาขนาดความกวางของสเหลยม สามารถเรยกใชฟงกชนไดดงน
myRectangle.Width();
จะเหนไดวา เราสามารถใสทงตวแปรและฟงกชนลงในคลาสได ซงจะท าใหเราสามารถจด
กลมของตวแปรและฟงกชนทท างานรวมกนไวในคลาสเดยวกนได เมอน าไปสรางเปนวตถ ตวแปร
และฟงกชนเหลานนกจะถกสรางขนมาใหม ไดอกนบครงไมถวน โดยทไมตองไปสรางตวแปรและ
ฟงกชนนนซ าอกครง ท าใหการเขยนโปรแกรมส าหรบงานทจ าเปนตองคดในเชงวตถ เชน เกมสและ
โปรแกรม Visio จะสามารถใชประโยชนจากภาษา C++ ไดเปนอยางด
ในหนงสอเลมนจะอธบายถงหลกการเขยนโปรแกรมเชงวตถ สวนประกอบตางๆ ในการเขยน
โปรแกรมเชงวตถ เชน คลาส (Class) การซอนขอมล (Encapsulation) การสบทอด (Inheritance) การ
เปลยนรปไดหลากหลาย (Polymorphism) การท าฟงกชนโอเวอรโหลด (Overloading Function) การ
ท าฟงกชนคอนสตรคเตอร และฟงกชนดสตรคเตอร เปนตน
1.3 C กบ C++
ภาษา C เปนภาษาทนยมใชในการเขยนโปรแกรมโดยทวไป ซงสามารถเขยนไดถงระดบลาง
ท าใหสามารถตดตอกบฮารดแวรไดโดยตรง หรอเขยนผสมกนระหวางภาษา C กบภาษาแอสแซมบล
อยางไรกตามหากเขยนโปรแกรมดวยภาษา C++ จะเขยนไดงายกวา แมวาจะไมไดใชความสามารถ
เชงวตถกตาม แลวภาษา C++ กสรางมาจากภาษา C ท าใหนกเขยนโปรแกรมทเขยนภาษา C เปนอย
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
5
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
สามารถเขยนโปรแกรมดวยภาษา C++ ไดอยางงายดาย ตวอยางความแตกตางระหวางภาษา C กบ
C++ มดงน
□ ภาษา C ไมมคลาสและวตถ ค าสงยอยจะตองถกสรางในฟงกชนเทานน
□ สตรคเจอรในภาษา C ไมมฟงกชน
□ ภาษา C ไมสนบสนนฟงกชนโอเวอรโหลด ซงเราไมสามารถสรางฟงกชนทมชอเดยวกนแตม
พารามเตอรตางกนได
□ ภาษา C ไมม new และ delete นกพฒนาโปรแกรมตองใช malloc() และ free() ในการขอจอง
หนวยความจ าและยกเลกการใชหนวยความจ า
□ ภาษา C ไมมตวแปรแบบอางอง โดยการนยาม ชนดขอมล&
แตอยางไรกตามภาษา C กบ C++ มความเหมอนกน (ยกตวอยาง) ดงน
□ ชนดขอมล int, double, char, float เปนตน
□ ตวประมวลผลกอน #include, #define เปนตน
□ การควบคมการไหลของโปรแกรม if, while, do, for เปนตน
□ ตวด าเนนการ + - * / = == != < > += ++ -- เปนตน
1.4 ลกษณะเดนของภาษา C++
ภาษา C++ สามารถน ามาเขยนโปรแกรมเชงโครงสรางโมดลควบคกบการเขยนโปรแกรมเชง
วตถได ท าใหมความยดหยนในการเขยนโปรแกรมทใชงานจรงเปนอยางมาก ภาษา C++ มขอดหลาย
ประการ โดยเฉพาะการเขยนโปรแกรมเชงวตถ ซงไมมในภาษา C อยางไรกตาม ภาษา C++ ไดถก
สรางมาจากภาษา C ดงนนไวยากรณและภาษาจงมรปแบบเดยวกนกบภาษา C อกทง ผเขยนได
เลอกใช Visual C++ เปนตวคอมไพลส าหรบเขยนโปรแกรมใหท างานบนระบบปฏบตการวนโดวส
ซงโครงสรางของ Visual C++ เหมาะสมกบการเขยนโปรแกรมเชงเหตการณ ท าใหสามารถพฒนา
โปรแกรมใหท างานบนระบบปฏบตการวนโดวส ทท างานแบบหลายงาน (Multi-Tasking) ได อกทง
Visual C++ มคลาส MFC เปนคลาสหลกทใชในการเขยนโปรแกรมเชงวตถ ซงเปนคลาสทคลมการ
ท างานของไลบราร Win32 ท าใหการเขยนโปรแกรมเพอท างานบนระบบปฏบตการวนโดวส มความ
สะดวกมากยงขน ลกษณะเดนของภาษา C++ ทถกพฒนาโดย Visual C++ มดงน
6
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ความคนเคยจากภาษา C นกพฒนาทเคยเขยนโปรแกรมดวยภาษา C มาแลว จะสามารถเรยนร
ภาษา C++ ไดอยางงายดาย ชนดขอมล ไวยากรณภาษา การควบคมโปรแกรม มรปแบบเหมอนกนกบ
ภาษา C มบางอยางทมเพมเตมในภาษา C++ เทานน อยางไรกตาม ภาษา C++ มความซบซอน
มากกวาภาษา C หลายประการ นกพฒนาตองใชความพยายามมากกวาภาษา C อกทงผเขยนใชตว
คอมไพล เปน Visual C++ และเขยนในรปแบบ ดอกควเมนต/วว ท าใหการเขยนโปรแกรมยาก
มากกวาภาษา C++ ทเขยนดวยตวคอมไพลแบบอนๆ
ท างานไดเรว ภาษา C++ ทเขยนในต าราเลมน ถกพฒนาโดย Visual C++ ซงท างานบน
ระบบปฏบตการวนโดวสเปนตวคอมไพล ไฟลโปรแกรม .exe ทถกสรางจาก Visual C++ ถอวา
ท างานไดเรวทสดเมอเทยบกบ วชวลเบสก บอรแลนด C++ เดลไฟ และ จาวา JDK ท าให Visual C++
เปนตวคอมไพลทเหมาะส าหรบการเขยนโปรแกรมในทกระดบ ตงแตระดบงาย เชน โปรแกรม
Paintbrush เครองคดเลข จนถงงานทซบซอนมาก เชน เกมสวางแผนโดยใชปญญาประดษฐ
โปรแกรมตระกลไมโครซอฟทออฟฟซ โปรแกรมจ าลองการท างาน โฟโตชอป และโปรแกรม
ปองกนไวรส เปนตน
โปรแกรมเชงวตถ C++ เปนภาษาทใชในการเขยนโปรแกรมเชงวตถ ดวยจดประสงคในการสราง
ภาษา C++ ขนมา เพอแกปญหาในสงทภาษา C ท าไมได ซงกคอความสามารถในการเขยนโปรแกรม
เชงวตถ นกพฒนาจะไดเรยนรแนวคดเชงวตถทมในต าราเลมน เชน คลาส การซอนขอมล การสบ
ทอด การเปลยนรปของฟงกชนและวตถ ความสามารถในเชงวตถนไมมในภาษา C
การเขยนโปรแกรมใหมประสทธภาพสงสด ในการเขยนโปรแกรมดวยภาษา C หรอ C++ ม
ขอดในเรองความยดหยนของตวภาษา ชดค าสงของภาษา C++ สามารถลดรปท าใหค าสงสนลง
กะทดรด และท างานไดเรวขนกวาเดม หากตองการเปนนกพฒนาทด ในระหวางเขยนโปรแกรมตอง
พจารณาเรองการลดรปค าสงเพอใหการเขยนโปรแกรมกระชบทสด และท างานไดเรวทสด จงจะท า
ใหโปรแกรมมประสทธภาพสงสด เชน หากตองการเขยนค าสงในการตรวจสอบการจอง
หนวยความจ า สามารถเขยนค าสงไดดงน [2]
p = (int *)malloc( 10 * sizeof(int) );
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
7
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
if( p != NULL) {
…
}
หากพจารณาจากค าสงขางบน NULL ถกนยามไวในภาษาใหมคาเปน 0 ดงนนค าสง if( p != NULL)
จงเปนการเปรยบเทยบ if( p != 0 ) ซงขอก าหนดในภาษา C หรอ C++ ในเรองความเกยวของกน
ระหวางตวเลขกบตรรกะ มดงน
ตวเลข ตรรกะ
0 จรง 0 เทจ
ตวเลขใดๆ ทมคาไมเทากบศนย ในภาษา C หรอ C++ จะใชแทนตรรกะเปนจรง หากตวเลขมคาเปน
ศนยในทางตรรกะใหเปนเทจ ดงนนค าสง if( p != NULL ) จงสามารถเขยนไดเทยบเทากบ if( p ) ซง
เราสามารถลดรปค าสงในการขอจองหนวยความจ าใหกระชบและท างานไดเรวกวาเดมได ดงน
if( p = (int *)malloc( 10 * sizeof(int) ) ) {
…
}
จากเดม ฟงกชน malloc จะตองจองหนวยความจ าแลวคนต าแหนงหนวยความจ าไวท p (ให p ชไปท
ต าแหนงหนวยความจ าทจองได) แลวน ามาตรวจสอบวา p ไมเทากบ NULL หากเปนจรง ค าสงใน if
กจะถกเรยกใชงาน ในชดค าสงใหมทกระชบกวาเดม มการท างานโดยฟงกชน mal loc จะตองจอง
หนวยความจ าแลวคนต าแหนงหนวยความจ าไวท p หากสามารถจองหนวยความจ าได ชดค าสงใน if
กจะถกเรยกใชงานทนท โดยไมมการท างานทางตรรกะ ท าใหการท างานเรวมากขนกวาเดม
โปรแกรมเชงเหตการณ การท างานบนระบบปฏบตการไมโครซอฟทวนโดว เปนการท างาน
แบบหลายงาน ดงนนงานแตละงานจะเกดขนไมพรอมกน และไมเรยงตามล าดบ เชน การวาดหนาจอ
8
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
การกดแปนพมพ การกดเมาส เปนตน อกทงในการท างาน ณ จงหวะเวลาหนง มหลายโปรแกรม
ท างานพรอมกน ซงจะเหนไดวา งานทเกดขนจะไมทราบวาจะเกดขน ณ เวลาใด ดงนนการมกลไกท
จะจดการการท างานของระบบปฏบตการใหสามารถท างานได จงเปนเรองทซบซอนมาก กลไกท
ระบบปฏบตการวนโดวสไดสรางขนคอการท างานตามเหตการณทเกดขน ซงระบบปฏบตการ
วนโดวสจะคอยตรวจจบเหตการณตางๆทเกดขน จากนนจะสงขาวสาร (Message) ไปยงโปรแกรม
เมอโปรแกรมไดรบขาวสาร ฟงกชนทไดเชอมตอเขากบขาวสารนนๆ กจะถกเรยกใชงาน การเขยน
โปรแกรมดวย Visual C++ จะชวยใหนกพฒนามองเหนภาพการเขยนโปรแกรมเชงเหตการณไดใน
ระดบลกมากกวาการเขยนดวยภาษาอนๆ
ความปลอดภย ในภาษาสมยใหม จะมกลไกในการตรวจสอบการท างานของโปรแกรม เรยกวา
การจดการขอผดพลาด (Exception Handling) ซงในปจจบนความสามารถนมอยในเกอบทกภาษา
เชน จาวา เดลไฟ และ C++ เปนตน ค าสงวนทใชในการท างานนไดแก try catch throw ซงค าสงทอย
ภายใน t r y { . . . } จะถกสงใหท างาน หากเกดขอผดพลาดใดๆ เกดขน เชนขอผดพลาดในการจอง
หนวยความจ า (NULL pointer exception) ขอผดพลาดจะถกขวาง (Throw) ออกมา และควา (Catch)
ขอผดพลาดนนโดย c a t c h ดงนนเราสามารถปองกนการเกดความผดพลาดทรายแรงไดโดยอาศย
ความสามารถน ซงจะท าใหโปรแกรมทเขยนดวยภาษา C++ มความปลอดภยมากขน อยางไรกตาม
หากเกดขอผดพลาด โปรแกรมจะหยดการท างานทนท
1.5 หนวยความจ าและการใชงาน
ในการเขยนโปรแกรมดวยภาษา C หรอ C++ นน ลกษณะเดนทส าคญของตวภาษาคอ ตวช
(Pointer) ซงเปนจดเดนทมประโยชนมากของภาษา C++ และใชในการชไปยงหนวยความจ าทขอจอง
จากระบบปฏบตการ หากตองการจองหนวยความจ าจากระบบปฏบตการ จะสามารถท าไดและ
สามารถจองไดเทาทระบบจะมให นอกจากนนระบบปฏบตการไมโครซอฟทวนโดวส ยงมการสราง
หนวยความจ าเสมอนขนมาดวย ซงท าใหระบบปฏบตการวนโดวสใหบรการหนวยความจ ากบ
โปรแกรมตางๆ ไดมากกวาทเปนจรง ดงนน
Available Memory = Physical Memory + Virtual Memory
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
9
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ซงกคอจ านวนหนวยความจ าทระบบปฏบตการสามารถใหบรการได = หนวยความจ าทางกายภาพ +
หนวยความจ าเสมอน โดยท หนวยความจ าทางกายภาพคอหนวยความจ าทตดตงไวในเครอง และ
หนวยความจ าเสมอนคอหนวยความจ าทระบบปฏบตการสรางขนมา
การขอจองหนวยความจ ากคอการขอใชพนทในหนวยความจ าทมอยในระบบอยางถกตองโดย
ระบบปฏบตการจะท าหนาทในการแบงสรรหนวยความจ าทมอย ใหโปรแกรมตางๆ ใชงานอยางไมม
การขดแยงกน และไมมการใชงานทบซอนกบหนวยความจ าของโปรแกรมอน ๆ ดงนนเมอมการขอ
จองหนวยความจ า เราจ าเปนตองใชอยางระมดระวง ไมใหมการอางถงต าแหนงหนวยความจ าผด
ต าแหนง โดยปกตหนวยความจ าจะถกแบงออกเปนเซกเมนต (Segment) โดยทแตละเซกเมนตคอ
พนทในหนวยความจ าซงจะมรหสของจดเรมตนและจดสนสดของเซกเมนตนนๆ ซงโปรแกรมจะไม
มสทธในการเขยนขอมลลงในหนวยความจ า หากไมไดรบอนญาตจากระบบปฏบตการ หาก
โปรแกรมยงฝนท าโดยอางถงต าแหนงหนวยความจ าทไมไดขอจองใชงาน จะท าใหเกดขอผดพลาด
เชน ความผดพลาดในการปกปองทวไป (General Protection Faults) หรอขอผดพลาดของโปรแกรม
ทไมสามารถกกบได (Unrecoverable Application Errors) เปนตน
เมอโปรแกรมถกสงใหท างาน ระบบปฏบตการจะจองหนวยความจ าส าหรบโปรแกรมนนๆ
โครงสรางของการจดการหนวยความจ าใหโปรแกรมแสดงดงรปท 1-1
รปท 1-1 การ
จดการหนวย
ความจ า
เมอมการเรยกใชงานโปรแกรม ตวแปรตางๆ จะถกเกบไวในสแตก (Stack) ซงเปนพนททถกจองให
ใชงานจากระบบปฏบตการ พนทของสแตกมขนาดเลกท าใหเกบขอมลไมไดมาก (ก าหนดขนาด
สแตกทตวคอมไพลได) หนวยความจ าทเราขอจองเมอมการท างานของโปรแกรมแลวนน จะมการ
เกบขอมลไวทฮพ (Heap) โดยฮพเปนหนวยความจ าสวนทเหลอทวางอย ซงมพนทใหญกวาพนทของ
สแตกมาก เพราะเปนหนวยความจ าสวนทเหลอเทาทระบบปฏบตการจะสามารถมองเหนได
สแตกเปนพนททถกจองไวใหโปรแกรมทถกเรยกใชงานส าหรบเกบ ฟงกชน และพารามเตอร
ตาง ๆ ของโปรแกรม
BSS
Block Started by Symbol/
10
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
□ โดยทวไป สแตกเปนหนวยโครงสรางขอมล มรปแบบการจดล าดบขอมลเปน เขากอน ออกท
หลง (First in, Last out)
□ สแตกของฟงกชนมประโยชนทส าคญ ในการเกบต าแหนงหนวยความจ าสงกลบ (R e t u r n
Address) ซงเปนต าแหนงหนวยความจ า ทตองการกระโดดกลบไป เมอฟงกชนท างานเสรจ
สนแลว
□ สแตกมประโยชนส าหรบเกบขอมล โดยฟงกชนจะท าการพชขอมลทเปนพารามเตอรของ
ฟงกชน และตวแปรแบบโลคอล (Local Variable) ลงในสแตก และพอปขอมลออก เมอ
ฟงกชนนนท างานเสรจสนแลว
□ เมอจบการท างานของฟงกชน ขอมลในสแตกจะน ามาใชไมไดอก โดยอาจถกลบทงไป
ทงหมด หรออาศยการเลอนตวชสแตก
สแตกจะถกสรางขนเพอใชในการเกบขอมลของฟงกชนทก าลงท างานอย ซงเรยกวาคอลสแตก (Call
Stack) ซงเปนสแตกทถกสรางขนมาเมอฟงกชนถกเรยกใชงาน ชนดของสแตกแบบนเรยกอกอยางวา
เอกซควชนสแตก (Execution Stack) คอนโทรลสแตก (Control Stack) ฟงกชนสแตก (Function
Stack) และรนไทมสแตก (Run-Time Stack) หรอเรยกสนๆ วา สแตก
(Return Address)
.
.
A
B
(Return Address)
รปท 1-2 โครงสราง
การจดวางคอลสแตก
(Call Stack Layout)
เมอฟงกชนใดถกเรยกใชโดยฟงกชนหนง ฟงกชนทถกเรยกใชจะตองคนการท างานกลบไปยงจดท
ถกเรยกใชเมอท างานเสรจแลว ซงคาต าแหนงหนวยความจ าทตองคนกลบจะถกพชไวในสแตก เมอ
เรมตนท างาน แลวจะถกพอปออกจากสแตกเมอจบการท างานของฟงกชน หากฟงกชนทถกเรยกใช
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
11
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ไปเรยกใชฟงกชนอน ฟงกชนทเรยกใช กจะตองพชคาต าแหนงหนวยความจ าทตองการสงกลบ ไป
ไวในสแตกของฟงกชนทจะเรยกใช ซงการท างานจะถกสงตอไปยงฟงกชนทถกเรยกใช และจะคน
การท างานกลบมายงผทเรยกฟงกชนเปนทอดๆ ไป ซงท าใหความสามารถในการท าฟงกชนเรยก
ตนเอง (Recursive Function) สามารถท าไดดวยกลไกแบบน ดงแสดงในรปท 1-2 หากฟงกชน A ถก
เรยกใชโดยฟงกชน B สแตกของฟงกชน A จะอยดานบน และจะพชคาต าแหนงหนวยความจ าท
ตองการสงกลบการท างานมายงฟงกชน B ไปเกบไวทสแตกของฟงกชน A ดงนนเมอฟงกชน A
ท างานเสรจสน กจะพอปขอมลออกมาจนกระทงได ต าแหนงหนวยความจ าสงกลบ กจะกระโดด
กลบไปยงต าแหนงหนวยความจ านน
เมอฟงกชนสนสดการท างาน ฟงกชนจะถกน าออก (Unload) จากหนวยความจ า รวมทงขอมล
ในสแตกดวย ซงท าใหฟงกชนอนๆ สามารถใชหนวยความจ า ณ ต าแหนงนนได ดงนนหนวยความจ า
จะถกน ามาใชซ า ท าใหตวแปรแบบโลคอล ซงถกสรางในฟงกชน ไมสามารถจะน าไปใชไดอก
หลงจากฟงกชนจบการท างานไปแลว หรออาจสรปไดวาวงจรชวตของตวแปรแบบโลคอลจะเกด
และตายพรอมกบฟงกชนนนเอง
ฮพเปนหนวยความจ าทสงวนใวใหโปรแกรมใชงาน ส าหรบเปนหนวยความจ าชวคราว ซง
หนวยความจ าทถกขอจองและขนาดของมน อาจจะไมทราบไดจนกวาโปรแกรมนนจะถกสงให
ท างาน โปรแกรมทถกเรยกใชงานสามารถขอจองหนวยความจ าทวางอยได และใชงานในพนททถก
จอง หลงจากใชงานเสรจแลวกสามารถขอยกเลกหนวยความจ าสวนนนได
□ ฮพเปนพนทหนวยความจ าสวนทเหลอของโปรแกรมทงหมด
□ โปรแกรมเกบขอมลไวทฮพ โดยทขอมลจะตองคงอย แมวาฟงกชนทหอหมชดค าสงในการ
ขอจองหนวยความจ าจะจบการท างานไปแลว
□ ฮพใชเกบคาซงมวงจรชวตยาวกวาตวแปรแบบโลคอล แตสนกวาตวแปรแบบโกลบอล
□ โดยทวไปเราจะใชวธการจองหนวยความจ าแบบพลวตในการขอจองหนวยความจ าเพอใช
งาน ซงหนวยความจ าทขอจองไดจะเกบไวทฮพ
โดยทวไปหนวยความจ าจะถกขอจองและน ากลบมาใชใหม ในขณะทโปรแกรมก าลงท างาน
โดยระบบปฏบตการจะท าการจดการ และบรหารการใชหนวยความจ าใหมประสทธภาพและ
ปลอดภยมากทสด (การท างานของโปรแกรมหนง อาจจะมผลท าใหอกโปรแกรมหนงเกด
12
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ขอผดพลาดได หากไมไดถกปกปองโดยระบบปฏบตการ) หนวยความจ าทไมถกใชงานเปนสวนท
เกบฮพ ฮพเปนโครงสรางขอมลแบบพลวต (Dynamic Data Structure) ซงสามารถขอใชงานและคน
หนวยความจ าได โดยเรยกใช malloc และ free ส าหรบภาษา C หรอ new และ delete ส าหรบ C++
ซง ระบบปฎบตการ จะยอมใหโปรแกรมจองและยกเลกการใชหนวยความจ า ตามขนาดทตองการได
ในขณะรน (Run Time) แทนทจะเปนการก าหนดขนาดหนวยความจ าตายตวแบบสแตก
รปท 1-3 โมเดล
หนวยความจ าใน
ทางตรรกะ (Logical
Memory Model)
แบบสแตกและฮพ
ดงนนพนทการใชงานแบบฮพ จะไมขนอยกบฟงกชนหรอโปรแกรม ขนาดของฮพจะขนอยกบพนท
หนวยความจ าทระบบปฏบตการสามารถใหใชงานได ดงนนหากเราตองการใชพนทหนวยความจ า
จ านวนมาก กควรจะสรางไวทฮพ หากขอมลทจดเกบไมมากนก กสามารถเกบขอมลไวทสแตกได
นกพฒนาจะไดศกษาการขอใชหนวยความจ าแบบตางๆ ซงอาจมการเกบขอมลไวทสแตกหรอฮพ
ขนอยกบรปแบบการขอจองหนวยความจ า
ดงนนหากเรามการใชงานตวแปรทวไป และตวแปรแบบอะเรย หรอแมกระทงตวชเอง ตว
แปรตางๆ เหลานจะมการเกบไวทสแตก ซงจะท าใหเราไมสามารถสรางอะเรยทมขนาดใหญๆ ได
เนองจากขอจ ากดของสแตกนนเอง เชนหากเราสรางอะเรยขนาด 1000000 หนวย โดยใหสรางไวใน
ฟงกชนใดๆ เชน ฟงกชน main ดงน
int _tmain(int argc, _TCHAR* argv[]) {
int A[1000000];
}
เราสามารถคอมไพลผานได แตเมอสงใหโปรแกรมท างานจะเกดขอผดพลาด ดงรปท 1-4
A
A
A
B
B
B
C
C
C
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
13
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
รปท 1-4 ขอผดพลาด
ทเกดขนจากการใช
พนทสแตกเกนกวา
ทก าหนด
เนองจากเราขอใชพนทของสแตกมากเกนไปนนเอง
ซงเราสามารถแกปญหานไดโดยการขอจองหนวยความจ าแบบพลวต โดยการใชตวช ชไปยง
ต าแหนงหนวยความจ าทขอจองได โดยมรปแบบดงน
ชนดขอมล* ตวแปร;
เชน
int* a;
ลกษณะการก าหนดตวแปรแบบน เปนการก าหนดใหตวช a เปนตวแปรทสามารถชไปยงต าแหนง
หนวยความจ าทตองการได โดยตองเปนตวชแบบ int
การขอจองหนวยความจ าสามารถท าไดโดยการเรยกใชฟงกชนจาก malloc.h ซงมฟงกชนให
เรยกใชมากมายเชนฟงกชน malloc() ซงมรปแบบดงน
void *malloc( size_t size );
ฟงกชน m a l l o c ( ) ท าหนาทในการจองหนวยความใหเรา เมอจองไดแลว ฟงกชนจะท าการสงคา
ต าแหนงหนวยความจ าทขอจองไดแบบ void* (กรณาอานเรอง void* เพมเตม) ซงผเรยกใชงาน
สามารถทจะแปลงชนดของขอมลไปเปนแบบใดกไดเชน i n t * หรอ f l o a t * การแปลงชนดขอมล
เรยกวาการท าคาสตงแบบชดเจน (Explicit Type Casting) เชน
a = (int *)malloc( 10 * sizeof(int) );
โดยท (int *) เปนสวนของการท าคาสตงแบบชดเจน ซงท าหนาทในการแปลงชนดขอมลแบบ void*
14
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ไปเปนแบบ int* เนองจาก int* ไมสามารถชไปยงต าแหนงหนวยความจ าทเปน void* ได หาก
ฟงกชน malloc ไมสามารถจองหนวยความจ าได คา 0 (NULL) จะถกสงออกมาจากฟงกชน malloc
แทน ตวแปร size เปนตวแปรทใชในการก าหนดขนาดของขอมลในหนวย byte ทตองการขอจอง ซง
โดยทวไปสามารถก าหนดไดจาก จ านวนชดขอมล x ขนาดของชนดขอมล
การจองหนวยความจ าในภาษา C++ สามารถใชค าสงวน new ในการจองได ซงจะมรปแบบ
งายกวาการใช malloc และสามารถใชในการจองหนวยความจ าใหอนสแตนซของคลาสได เชน
a = new int[10];
ซงเปนการจองหนวยความจ า จ านวน 10 หนวย แตละหนวยมขนาดเทากบขนาดของ in t เมอจอง
หนวยความจ าไดแลวเราสามารถอางถงต าแหนงหนวยความจ าหรออางถงขอมลของ a ได ดงน
*(a + 1) หรอ a[1]
ซงมความหมายเดยวกน คอเปนการอางถงขอมลท a ชอย ณ ต าแหนงหนวยความจ าทเพมจาก a ไป 1
หนวย เมอเราสรางตวแปรแบบตวชขนมา ตวแปรนนจะถกสรางและเกบไวทสแตก หากมการขอจอง
หนวยความจ าโดยใช malloc หรอ new หนวยความจ าทขอจองไดจะถกสรางและเกบไวทฮพ ท าให
ไมเกดปญหาในเรองขอจ ากดของการจองหนวยความจ า ทไมสามารถจองไดมากอยางเชนสแตก
จากรปท 1-5 เมอสรางตวชทมชนดขอมลแบบ int ตวช a จะถกสรางไวทสแตก ซงขนาดพนท
ทขอใชจะเทากบ int* ดงนน ตวช a จงสามารถเกบต าแหนงหนวยความจ าทมชนดขอมลแบบ int ได
int* a;
10
a 0F005A
a = new int(10);
0F005A
รปท 1-5 ขนตอนการ
ท างานของการจอง
หนวยความจ า ( ) หมายถงการก าหนด
คาเรมตนลงใน
ต าแหนงหนวยความจ า
ทขอจองได
1 หมายถงเลอนไป 1 หนวยขอมลเชน หาก int มขนาด 4 ไบต ดงนน 1
หมายถงเลอนไป 1 หนวยขอมล ซงกคอเลอนไป 4 ไบตนนเอง
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
15
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
หรอกลาวอกนยหนงคอ a สามารถชไปยงต าแหนงหนวยความจ าทเกบขอมลเปนชนด int ได จากนน
เมอเราขอจองหนวยความจ าโดยใชค าสง a = new int(10); ระบบปฏบตการจะหาพนทหนวยความจ า
ทยงไมมการใชงานทฮพ จากนนจะสงคาต าแหนงหนวยความจ าเรมตนกลบไปเกบไวท a ซงกคอ a ช
ไปยงต าแหนงหนวยความจ าเรมตนทขอจองไดนนเอง
จะเหนไดวา กลไกการท างานแบบน ท าใหเราไมมขอจ ากดในการขอใชหนวยความจ า เนอง
จากฮพ กคอพนทหนวยความจ าทเหลอทระบบปฏบตการจะสามารถใหใชงานได เราจงสามารถจอง
ไดมากเทาทตองการ ตราบใดทยงมหนวยความจ าเหลอเพยงพอ ดงนนหากเราขอจองหนวยความจ า
เพอเกบขอมลภาพขนาด 1900*1200 ซงตองใช 2,280,000 หนวยขอมล โดยใชค าสง
ซงจะท าใหเราสามารถจองหนวยความจ าและใชงานได เนองจากหนวยความจ าทขอจองจะเกบไวท
ฮพ ดงเชนการท างานในรปท 1-5 ซงจะเหนไดวาเราไมสามารถท าได หากใชอะเรยในการขอใช
พนทหนวยความจ า จ านวนมากเชนน
int *NewVector(int n) {
int *tmp, i;
if( !(tmp = new int[n]) ) {
printf("Not enough memory to allocate buffer\n");
return NULL;
}
for(i=0; i<n; i++) {
tmp[i] = i;
}
return tmp;
}
unsigned char* p;
p = new unsigned char[1900 * 1200];
สรางตวช p แบบ unsigned char *
จองหนวยความจ าจ านวน 1900*1200 ชด
ตวอยางท 1-1 การขอจองหนวยความจ าผานฟงกชน NewVector
16
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
void DeleteVector(int *v) {
delete v;
}
#define N 10
int _tmain(int argc, _TCHAR* argv[]) {
int *v1, *v2, i;
v1 = NewVector(N);
v2 = NewVector(N);
for(i=0; i<N; i++) {
printf("v1[%d] x v2[%d] = %d\n", i, i, (v1[i]*v2[i]) );
}
printf("Press any key to deallocate pointer!\n");
DeleteVector(v1);
DeleteVector(v2);
return 0;
}
ตวอยางท 1-1 เปนการขอจองหนวยความจ า โดยเรยกใชฟงกชน NewVector ซงตวฟงกชนจะสง
ต าแหนงหนวยความจ าทจองไดกลบ โดยการเรยกใชตองก าหนดจ านวนชดขอมลทจะขอจอง ดงนน
ตวแปรทจะมารบคาทสงกลบจากฟงกชน NewVec tor ตองเปนตวชทมชนดขอมลเปน in t จงจะ
สามารถท างานได
1.6 ตวแปรแบบอางอง (Reference Variable)
ตวแปรแบบอางอง เปนรปแบบหนงของการอางถงต าแหนงหนวยความจ าของตวแปร ในการ
เขยนโปรแกรมดวยภาษา C++ (ความสามารถนไมมในภาษา C) ตวแปรทก าหนดโดยการนยาม ชนด
ขอมล& เปนการอางองของชนดขอมลนนๆ และตองถกก าหนดคาต าแหนงหนวยความจ าตงแตเมอ
ตวแปรนนถกนยามขนมา รปแบบทวไปของการนยามตวแปรแบบอางอง เปนดงน
ขอควรคด
เราสามารถอางถงขอมลในตวชได โดยใช
รปแบบเดยวกนกบอะเรย ดงนนเราอาจสรป
ไดวา ไดมมมองของอะเรย ตวชคออะเรยท
ไมจ ากดขนาดนนเอง
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
17
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ชนดขอมล& ตวแปรแบบอางอง = lvalue;
การก าหนดตวแปรแบบอางอง จะกระท าการเมอตวแปรนนถกนยามขนมา ดงนนคาเรมตนของตว
แปรอางอง จะตองเปนไปตามรปแบบตวกระท าทางซาย (lvalue) เชน ตวแปร a อะเรย x[i] และตวช
*p t r เปนตน หากเปนคาคงทหรอผลลพธทไดจากการกระท านพจน จะไมสามารถใชเปนคาเรมตน
ของตวแปรแบบอางองได ดงนน
int b = 10;
int& a = b;
จะเปนการก าหนดตวแปรแบบอางองไดถกตอง ซงการเขยนแบบนมความหมายวาตวแปร b และ a
อางถงหนวยความจ าต าแหนงเดยวกน ดงนนจงเปรยบเสมอนตวแปร a เปนชออกชอหนง (A l i a s
Name) ของตวแปร b นนเอง การใชงานตวแปรแบบอางองจะกระท าไดเหมอนตวแปรปกตทวไป
หากเราก าหนดใหตวแปรแบบอางองท าการอางไปยงคาคงท หรอผลลพธทไดจากการกระท านพจน
int& wrong = 200;
int& opt = (2 + 3 - 5);
จะไมสามารถคอมไพลผานได เนองจากใชรปแบบไมถกตอง การนยามตวแปรแบบอางอง จะตอง
ก าหนดคาต าแหนงหนวยความจ าตงแตตอนเรมตน ซงต าแหนงหนวยความจ าทอางถง ไมสามารถ
เปลยนได ดงนน
จะท างานไดไมถกตอง โดย int& ref จะท าใหเกดขอผดพลาดขน และโปรแกรมจะคอมไพลไมผาน
เนองจาก ตวแปรแบบอางองตองก าหนดต าแหนงหนวยความจ าทจะอางถงตงแตตอนเรมตน สวน
การใชค าสง ra = c เปนการถายคาจากตวแปร c ไปเกบไวทตวแปร ra ไมใชการก าหนดการอางถง
int& ref;
int c = 20;
ra = c;
คอมไพลไมผาน
การแทนคา c ลงใน rc
18
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ดงนนค าสงนสามารถท างานได แตไมถกตองตามวตถประสงค เมอน าตวแปรแบบอางองไปอางถง
ต าแหนงหนวยความจ าของตวแปรอกตวหนง ตวแปรทงสองกจะอางถงหนวยความจ า ณ ต าแหนง
เดยวกน ดงแสดงในรปท 1-6
10
a
xint a = 10;int& x = a;
รปท 1-6 ความหมาย
ของการสรางตวแปร
แบบอางอง
ประโยชนหลกของการสรางตวแปรแบบอางองในภาษา C + + นน โดยทวไป จะใชในการสงคา
ต าแหนงหนวยความจ าเขาในฟงกชนโดยไมตองมการส าเนาขอมลไปยงสแตกของฟงกชน ซงจะชวย
เพมความเรวในการท างานของฟงกชนนนๆ นกพฒนาจะไดเรยนรความสามารถนในเรองฟงกชน
1.7 การเขาถงโดยออมแบบสองตอ (Double Indirection)
หากเราตองการขอใชพนทหนวยความจ าเพอเกบขอมลแบบเมทรกซ สามารถใชอะเรยแบบ
สองมตได เชน
int A[1000][1000];
ซงตวแปรแบบอะเรยสองมตกจะถกสรางและเกบไวทสแตกของโปรแกรม ดงนนหากสรางเมทรกซ
ทมขนาดใหญ จะท าใหโปรแกรมเกดขอผดพลาดขนเชนเดยวกบอะเรยแบบหนงมต เนองจากพนท
ในการเกบขอมลในสแตกมไมเพยงพอ เราสามารถแกปญหานไดโดยใชตวชแบบโดยออมสองตอ
เมอสรางตวแปรขนมาหนงตว เราสามารถเขาถงขอมลของตวแปรนนไดโดยตรง (D i r e c t
Access) คาทเกบในตวแปรนนจะจดเกบทต าแหนงหนวยความจ าของตวแปรนน เชนเมออางถง &x
จะหมายถงต าแหนงหนวยความจ าของ x ซงเกบตวเลข 20 ไว ณ ต าแหนงหนวยความจ านน หากน า
ตวช ptr (*ptr) ไปชทต าแหนงหนวยความจ าของตวแปร x เราสามารถเขาถงขอมลใน x ไดโดยออม
(Indirect) โดยผานตวช ptr โดยใชตวกระท า * ดงนนการใช *ptr กเปนการเขาถงขอมลท ptr ชอย
หาก ptr ชไปทต าแหนงหนวยความจ าของ x กจะเปนการเขาถงขอมลของตวแปร x นนเอง
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
19
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
เราสามารถสรางตวชแบบสองตอ (Double Pointer) ทสามารถเขาถงขอมลไดโดยออมแบบสองตอได
โดยมรปแบบดงน
ชนดขอมล** ตวแปร;
ซงตวกระท า ** เปนการก าหนดใหรปแบบของการเขาถงขอมล สามารถเขาถงไดโดยออมแบบสอง
ตอ ดงนนหากก าหนดให *pptr = ptr กเปนการก าหนดให *pptr เกบคาต าแหนงหนวยความจ าท ptr ช
อย ดงนน หากเราตองการเขาถงขอมลในตวแปร x กสามารถกระท าไดดงน
ภาพรวมการเขาถงโดยตรงและโดยออมแสดงดงรปท 1-7
โดยปกตการใชตวชทสามารถเขาถงขอมลไดโดยออมแบบสองตอ จะมการใชงานในบางกรณ
ทจ าเปน เชนการจองหนวยความจ าแบบเมทรกซ เพอเกบขอมลภาพ เปนตน อยางไรกตาม การจอง
หนวยความจ าส าหรบแบบสองมต กไมสามารถท าไดโดยตรง เชน
int x = 20;
int* ptr=NULL;
int** pptr = new int*;
ptr = &x;
*pptr = ptr;
printf("x=%d, *ptr=%d, **pptr=%d\n", x, *ptr, **pptr);
printf("&x=%p, ptr=%p, *pptr=%p\n", &x, ptr, *pptr);
สรางตวแปร x
สรางตวช ptr
สรางตวชแบบสองตอ
ให p ชไปท &x
ให *pptr ชไปท ptr
x
*ptr
**pptr
เขาถง x โดยตรง
เขาถง x โดยออมผาน *ptr
เขาถง x โดยออมสองตอผาน **pptr
double** A = new double[1000][1000]; ผดพลาด
20
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
รปท 1-7 การเขาถง
ขอมลโดยตรง
เขาถงโดยออม
และเขาถง
โดยออมสองตอ
จะเกดขอผดพลาดขน และไมสามารถคอมไพลผานได หากตองการจองหนวยความจ าเพอให
สามารถท างานไดแบบสองมต การจองหนวยความจ าเพอสรางเมทรกซ โดยใชตวกระท า **
หนวยความจ าจะมอยสองชดทจ าเปนตองมการสรางขนมา ชดแรกเปนหนวยความจ าทางดานแนวตง
หนวยความจ าชดนท าหนาทในการชไปยงหนวยความจ าทางดานแนวนอนในแตละชด สวนชดท
สองเปนหนวยความจ าทใชในการเกบขอมล ดงนนเมอเราตองการขอจองหนวยความจ า เราจง
จ าเปนตองจองหนวยความจ าทางดานแนวตงกอน จากนนจงขอจองหนวยความจ าทางดานแนวนอน
แลวสงต าแหนงหนวยความจ าทางดานแนวนอนในแตละชด ไปเกบไวทหนวยความจ าทางดาน
แนวตงในแตละหนวยขอมล เมอสรางตวช
float** A;
ขนตอนการจองหนวยความจ ามดงน (ขนาด R x C)
ขนตอนทหนง จองหนวยความจ าทางดานแนวตง
เมอขอจองหนวยความจ าไดแลว เราสามารถอางถงขอมลทเกบไวในต าแหนงหนวยความจ าแตละ
หนวยขอมลได แสดงดงรปท 1-8
A = new float*[R];
หรอ
A = (float **) malloc((unsigned) (R)*sizeof(float *));
จองโดยใช new
จองโดยใช malloc
20x
20*ptrptr
**pptr*pptrpptr
20
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
21
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ขนตอนทสอง จองหนวยความจ าทางดานแนวนอน
เมอท าการจองหนวยความจ าทางดานแนวนอนไดแลว คาต าแหนงหนวยความจ าเรมตนจะมการ
สงไปเกบไวท A[y] ซงจะท าให A[y] ชไปยงต าแหนงหนวยความจ าเรมตนของชดขอมลนนๆ นนเอง
ดงรปท 1-9
A[0]
A[R-1]
A = new float*[R]; รปท 1-8 การอางถง
หนวยขอมล
ทางดานแนวตง
for (int y=0; y<R; y++) {
A[y] = new float[C];
หรอ
A[y] = (float *) malloc((unsigned) (C)*sizeof(float));
if (!A[y]) {
printf("Can’t allocate memory for mat[%d]", y);
}
}
รปท 1-9 การจองหนวย
ความจ าเพอเกบขอมล
แบบสองมต A[0]
A[R-1]
A[y] = new float[C];A[0][0] A[0][C-1]
22
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
หากเราเขาใจโครงสรางการจองหนวยความจ าเพอเกบขอมลแบบสองมตแลว เราสามารถลดค าสงใน
การจองหนวยความจ าลงไดดงตวอยางท 1-2 ซงจะท าใหการจองหนวยความจ า กระท าเพยงแคสอง
ครง จากเดมตองจอง R+1 ครง
ตวอยางท 1-2 การจองหนวยความจ าส าหรบเกบขอมลแบบสองมต
double** newMatrix(int R, int C) {
double* tmp = new double[R*C];
double** M = new double*[R];
for(int y=0; y<R; y++) {
M[y] = tmp + (y * C);
for(int x=0; x<C; x++)
M[y][x] = 0.0;
}
return M;
}
จองหนวยความจ าขนาด R*C
จองหนวยความจ าใหตวชโดยออมสองตอ
ขนาด R
ให M[y] ชไปยง tmp + (y * C) เมอ y คอคา
ทางดานแกนตง และ C คอจ านวนชดขอมล
ทางดานแนวนอน
การจองหนวยความจ าดงตวอยางท 1-2 เปนการจองหนวยความจ าสองชด โดย double* tmp = new
double[R*C] เปนการจองหนวยความจ าขนาด R*C โดยให tmp ชไปยงต าแหนงหนวยความจ าทขอ
จองได การจองอกชด double** M = new double*[R] เปนตวชแบบสองตอ ซงท าหนาทในการเกบ
ต าแหนงหนวยความจ าของ t m p ทแบงออกเปนสวนๆ ตามขนาดของ C โดยอาศยการค านวณ
ต าแหนง tmp + (y * C) เมอ y มคามากขน ตวช tmp จะถกเพมต าแหนงไปครงละ C หนวยขอมล
1.8 องคประกอบการเขยนโปรแกรมดวย C++
โปรแกรมทเขยนโดยภาษา C + + ประกอบไปดวยฟงกชนและคลาส ฟงกชนเขยนขนมาเพอ
ก าหนดการท างานของงานทตองการ เชนฟงกชนในการค านวณหาพนทสเหลยม เปนตน คลาสเปน
องคประกอบหลกในการเขยนโปรแกรมเชงวตถ ซงเปนการนยามสงทตองการสรางขนมาโดยคดใน
เชงวตถ ภายในคลาสประกอบไปดวย ตวแปร และฟงกชน ซงฟงกชนเปนสวนประกอบทส าคญใน
การเขยนโปรแกรมเชงโครงสรางโมดลและเชงวตถ โดยสวนใหญน ามาใชในการแบงงาน แลวน ามา
เรยกใชภายหลง เพอความเปนระเบยบเรยบรอย อกทงเปนการชวยใหการแกไขโปรแกรมในแตละ
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
23
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
สวน และการดบกโปรแกรมเปนไปไดโดยงาย ในสวนนจะเปนการอธบายฟงกชนในรปแบบตางๆ
เชน สวนประกอบของฟงกชน การสงคาพารามเตอรเขาในฟงกชนแบบตางๆ การท าฟงกชนโอเวอร
โหลด ฟงกชนอนไลน ตวชฟงกชน และตวชชนด void (void *) โดยเฉพาะเรองตวชฟงกชนซงท า
หนาทเปนฟงกชนคอลแบค ซงเปนสวนทส าคญมากในการเขยนโปรแกรมเชงเหตการณ
1.8.1 ฟงกชน (Function)
ฟงกชนประกอบไปดวยค าสงหรอชดค าสง ซงจะท างานตามล าดบทไดก าหนดไว ภายใน
ฟงกชนสามารถสรางตวแปรขนมาไดเปนตวแปรแบบโลคอล (Local Variable) ซงขอบเขตของตว
แปร จะสามารถใชไดภายในฟงกชนเทานน การเขยนโปรแกรมทด จ าเปนตองมการแบงฟงกชนเปน
ฟงกชนยอยๆ เพอเปนการกระจายงาน และแยกงานออกตามขอก าหนดของแตละฟงกชน เราสามารถ
มองฟงกชนเปนหนวยค านวณได ดงรปท 1-10
รปท 1-10 ฟงกชนทถกมอง
ในรปแบบหนวยค านวณ
ขอก าหนดของฟงกชนประกอบไปดวยสวนหว (Header) และสวนตว (Body) สวนหวของฟงกชน
เปนการก าหนดรปแบบของฟงกชน สวนหวประกอบไปดวย ชนดขอมลทตองการสงคากลบ ชอ
ฟงกชน และพารามเตอรทตองการสงเขาในฟงกชน สวนตวฟงกชนประกอบดวยชดค าสง ซงตอง
เขยนไวภายในเครองหมาย { } รปแบบของฟงกชนมดงน
return_type function_name(type arg1, type arg2, …)
{
ประกาศตวแปร และชดค าสง
}
เมอ
return_type คอชนดขอมลทตองการสงคากลบ
function_name คอชอฟงกชน
type arg1 คอชนดขอมลและชอตวแปร
สวนหวของฟงกชน
สวนตวของฟงกชน
24
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
1.8.2 โปรโตไทปของฟงกชน
ในภาษา C หรอ C++ เมอสรางฟงกชนแลว จ าเปนตองมการสรางโปรโตไทปของฟงกชนดวย
รปแบบของโปรโตไทปของฟงกชนมรปแบบเหมอนการสรางฟงกชนโดยทวไป แตจะมเพยงสวน
หวของฟงกชน ทลงทายดวย ; ตวอยางการสรางโปรโตไทปของฟงกชนเปนดงน
int factorial(int n);
หากมการเรยกใชฟงกชน โดยทไมมการสรางโปรโตไทปของฟงกชน ตวคอมไพลจะไมสามารถ
คอมไพลโปรแกรมใหผานได เนองจากตวคอมไพลยงไมรจกรปแบบของฟงกชนทถกเรยกใช ซง
โดยปกต การคอมไพลจะกระท าจากบนลงลาง ดงนนโปรโตไทปของฟงกชนควรจะวางไวต าแหนง
ดานบนของโปรแกรม หลงจาก #include และการก าหนดตวแปรแบบโกลบอล
int fac(int n);
int _tmain(int argc, _TCHAR* argv[]) {
printf("%d\n", fac(5));
return 0;
}
int fac(int n) {
if (n == 0) {
return 1;
}
else {
return n * fac(n - 1);
}
}
ตวอยางท 1-3 เปนการสรางฟงกชน โดยมการก าหนดโปรโตไทปของฟงกชนไวทสวนบน
ตวอยางท 1-3 การก าหนดโปรโตไทปของฟงกชนและตวฟงกชน
โปรโตไทปของฟงกชน
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
25
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ดงนนเราจงสามารถเรยกใชงานฟงกชนจากทใดกได โดยไมตองวางฟงกชน m a i n ไวหลงสด
เนองจากการคอมไพล จะท าการคอมไพลจากตนไฟลไปยงทายไฟล โปรโตไทปของฟงกชนทถกวาง
ไวดานบน จะท าใหตวคอมไพลรจกและเรยกใชงานได
หากฟงกชนทสรางขนมาเปนสมาชกของคลาส โปรโตไทปของฟงกชนจะตองถกสรางไวใน
สวนของการก าหนดรปแบบคลาส ซงนกพฒนาจะไดเรยนรในเนอหาของการสรางคลาส
1.8.3 การเรยกใชฟงกชนและการสงคาเขาในฟงกชน
เมอมการเรยกใชฟงกชน คาพารามเตอรทปอนเขาในฟงกชน จะตองถกก าหนดอยางชดเจน
เนองจากการเรยกใชฟงกชนจะมการตรวจสอบ ในขณะคอมไพล (C o m p i l e T i m e) หากจ านวน
พารามเตอรและชนดขอมลไมตรงกบฟงกชนทไดสรางไว การคอมไพลกจะไมผาน คาทสงผานเขา
ไปในฟงกชนจะถกส าเนาไปเกบไวทพารามเตอรของฟงกชน หรออาจถกอางถง หรอถกชไปยงตว
พารามเตอรทปอนเขาไปในฟงกชน ขนอยกบรปแบบของการเรยกใชฟงกชน ซงจะไดกลาวถงใน
หวขอถดไป
fac(5);
ฟงกชน fac ถกเรยกใช โดยมการสงคาตวเลข 5 เขาไปในฟงกชน เลข 5 จะถกส าเนาไปเกบไวยงตว
แปร n (ดตวอยางท 1-3 ประกอบ) ซงเปนพารามเตอรของฟงกชน fac
ในภาษา C + + เราสามารถผานคาตวแปรเขาสฟงกชนไดหลายวธ แบบแรกคอสงคาเขาใน
ฟงกชนโดยคา (By Value) แบบทสองสงคาเขาไปในฟงกชนโดยใชการอางอง (By Reference) แบบ
ทสามโดยใชตวช (Pointer) ซงแตละแบบจะมประโยชนในการใชงานตางกนไป
1.8.4 การสงพารามเตอรเขาในฟงกชนโดยใชคา (Pas by Value)
เมอเราผานคาพารามเตอรเขาสฟงกชนโดยใชรปแบบสงพารามเตอรเขาในฟงกชนโดยใชคา คาทสง
เขาในฟงกชนจะมการเปลยนแปลงเฉพาะในฟงกชนเทานน ซงกลไกการท างานจะกระท าโดย การ
ส าเนาคาทสงเขามาไปเกบยงตวแปรทใชในการรบคา ซงตวแปรทใชในการรบคาจะเกบไวในสแตก
ของฟงกชนนนๆ
26
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
เมอฟงกชน cube ถกเรยกใช โครงสรางของฟงกชน cube จะถกสรางไวในหนวยความจ า ซงเรยกวา
กรอบสแตก (Stack Frame) โดยโครงสรางนจะใชการเกบขอมลแบบสแตก โดยการพช (Push)
ขอมลใสสแตก และพอป (Pop) ขอมลออกจากสแตก ดงนนเมอเรยกใชฟงกชน cube(x) คาในตวแปร
x จะถกส าเนาไปเกบไวในตวแปร d ซงเปนพารามเตอรของฟงกชน cube เมอคาในตวแปร d มการ
เปลยนแปลง กจะไมมผลกบคาในตวแปร x แตอยางใด เพราะเมอฟงกชนถกเรยกใช ตวแปร x และ d
ไมใชตวแปรเดยวกน ตวอยางท 1-4 จะไดผลลพธ y มคาเปน 27 และ x มคาเปน 3 เหมอนเดมไม
เปลยนแปลง โครงสรางกรอบสแตกแสดงดงรปท 1-11
ตวอยางท 1-4 การสงพารามเตอรเขาฟงกชนโดยใชคา
int cube(int d) {
d = d * d * d;
return d;
}
int _tmain(int argc, _TCHAR* argv[]) {
int x=3,y;
y = cube(x);
printf("x=%d, y=%d", x, y);
return 0;
}
ตวแปร d ถกสรางไวในสแตกเพอรอ
รบคาทสงเขามาในฟงกชน
สงคา x เขาในฟงกชน คาในตวแปร
x จะถกส าเนาไปไวในสแตกของ
ฟงกชน
รปท 1-11 โครงสรางกรอบ
สแตกของฟงกชน cube
หากเราตองการก าหนดคาเรมตนใหกบพารามเตอรในฟงกชน สามารถท าไดโดยก าหนดคานนไปท
ตวแปรของพารามเตอรทตองการไดเลย เชน
d
3
x cube
x d
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
27
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
void setFlag(bool bFlag = true) {
…
}
เมอมการเรยกใชฟงกชน เราสามารถสงคาเขาในฟงกชนหรอไมกได เชน setFlag(false) เปนการ
ก าหนดคา bFlag = false หรอหากเรยกใชฟงกชน setFlag() โดยไมมการสงคาเขาในฟงกชน กจะใช
คาเรมตนทก าหนดในฟงกชนโดยให bFlag = true นกพฒนาจะไดเหนรปแบบการเขยนฟงกชนใน
ลกษณะนในการเขยนโปรแกรมดวย Visual C++
1.8.5 การสงพารามเตอรเขาในฟงกชนโดยใชการอางอง (Pass by Reference)
การสงคาพารามเตอรเขาในฟงกชน ในภาษา C++ สามารถสงไดโดยใชการอางอง ซงเปนการ
ใชตวด าเนนการ & ในการสงคาแบบอางอง จะไมมการส าเนาขอมลระหวางตวแปรทสงเขามากบ
พารามเตอรในฟงกชน แตจะเปนการอางถง โดยใหพารามเตอรอางถงต าแหนงหนวยความจ าของตว
แปรทสงเขามา ดงนนตวแปรทสงเขามากบพารามเตอรของฟงกชนจงใชหนวยความจ ารวมกน
จากตวอยางท 1-5 การก าหนดรปแบบฟงกชนจะใชโอเปอเรเตอร & น าหนาพารามเตอรใน
ฟงกชน ดงนนในการเรยกใชงานจงท าไดโดย swapnum(a, b ) โดยไมจ าเปนตองอางถงต าแหนง
หนวยความจ าโดยใช & แตตวแปร i และ j ทเปนพารามเตอรของฟงกชน swapnum จะอางถง
ต าแหนงหนวยความจ าของตวแปร a และ b ตามล าดบ ซงเปนการใชต าแหนงหนวยความจ ารวมกน
นนเอง ความหมายของการอางองแสดงดงรปท 1-12
ค าแนะน า
ขอเสยของการเรยกใชฟงกชนโดยการสงพารามเตอรเขาสฟงกชนโดยใชคา คอจะตองมการส าเนาขอมล
จากพารามเตอรทสงเขาในฟงกชนไปเกบไวทสแตกในฟงกชนนนๆ ท าใหตองใชเวลาในการท างานมากขน
หากพารามเตอรทปอนเขาสฟงกชนมจ านวนมากๆ เชน การสงตวแปรแบบสตรคเจอร หรอการสงวตถเขาส
ฟงกชน เปนตน จะท าใหโปรแกรมมประสทธภาพลดลง
20
b
10
a
i j
รปท 1-12 การอางถงต าแหนง
หนวยความจ า
โดยใชตวแปรแบบอางอง
28
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ตวอยางท 1-5 การสงพารามเตอรเขาในฟงกชนโดยใชการอางอง void swapnum(int &i, int &j);
int _tmain(int argc, _TCHAR* argv[]) {
int a = 10;
int b = 20;
swapnum(a, b);
printf("A is %d and B is %d\n", a, b);
return 0;
}
void swapnum(int &i, int &j) {
int temp = i;
i = j;
j = temp;
}
ดงนนหากเปลยนคาในตวแปร i กเปนการเปลยนคาตวแปร a ดวย และตวแปร j กบ b กท างานใน
ท านองเดยวกน
หากตองการสงคากลบจากฟงกชนโดยใชการอางอง สามารถสงกลบได ทงนคาทสงกลบ
จะตองไมเปนตวแปรแบบโลคอลของฟงกชนนน เชน
เมอเรยกใชฟงกชน maxin t คาทสงกลบคอ ต าแหนงหนวยความจ าของตวแปรทมคาสงสด ดงนน
maxint(a, b) = 15 จงเปนการก าหนดคาให b มคา 15 หรอ maxint(a, b)++ เปนการเพมคาในตวแปรท
int& maxint(int& x, int& y) {
return (x>y ? x : y);
}
int a = 10, b = 20 ;
maxint(a, b) = 15 ;
maxint(a, b) += 10;
maxint(a, b)++;
นยามฟงกชน maxint ใหสงคากลบ
เปนการอางอง
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
29
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
มคาสงสดขนหนงคา
1.8.6 การสงพารามเตอรเขาในฟงกชนโดยใชตวช (Pass using Pointer)
การสงคาเขาในฟงกชนสามารถท าไดอกแบบ ซงเปนจดเดนทส าคญของการเขยนโปรแกรม
ดวยภาษา C หรอ C + + คอการใชตวช ความสามารถของตวชคอมนสามารถชไปยงต าแหนง
หนวยความจ าทตองการได เมอใชตวช คาทสงเขาในฟงกชนจะตองเปนต าแหนงหนวยความจ าของ
ตวแปรทสงเขามา เพอใหพารามเตอรในฟงกชนชไปยงหนวยความจ าของตวแปรนน
ในการใชตวชเพอรบคาพารามเตอรเขาในฟงกชน จะมความสามารถเทยบเทากบการใชการอางอง
เนองจากตวช a จะชไปยงต าแหนงหนวยความจ าของตวแปร x ดงนน (*a)++ กเปนการเพมคาท a ช
อยขนไปหนงคา ซงกเปนการเพมคาของตวแปร x นนเอง กลไกการท างานในลกษณะนท าใหไมตอง
ค าแนะน า
ขอดของการใชตวแปรแบบอางองคอ ในการเรยกใชฟงกชน จะไมมการส าเนาขอ
มลระหวางคาตวแปร
ทสงเขาในฟงกชน กบพารามเตอรของฟงกชน แตยงคงรปแบบการเรยกใชเหมอนตวแปรปกตทวไป
โดยไมตองม & หรอ * น าหนาตวแปร ท าใหการใชงานงาย และการท างานจะเรว
กวาการสงพารามเตอร
เขาฟงกชนโดยใชคา โดยเฉพาะการสงพารามเตอรเปนสตรคเจอรและวตถ
ตวอยางท 1-6 การใชตวชในฟงกชน
void Inc(int *a);
int _tmain(int argc, _TCHAR* argv[]) {
int x=1;
Inc(&x);
printf("x=%d\n", x);
return 0;
}
void Inc(int *a) {
(*a)++;
}
30
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
มการส าเนาขอมลจากตวแปรไปเกบไวทสแตกของฟงกชน ท าใหลดเวลาการท างานลง และท าให
คาตวแปรทสงเขาในฟงกชนมการเปลยนคาตามไปดวย ซงสามารถน าไปใชในการทดแทนการสงคา
กลบจากฟงกชน โดยมหลายพารามเตอร เนองจากการสงคากลบจากฟงกชน จะกระท าไดเพยงหนง
ขอมลเทานน รปท 1-13 แสดงความหมายของการใชตวช
10
x
Addr: 1000
void Inc(int *a) { (*a)++; }
Inc( &x );
รปท 1-13 การใชตวชเพอ
เปลยนคาภายในตวแปร
ทสงเขาฟงกชน
1.8.7 การใชตวชฟงกชน (Function Pointers)
โดยปกตเมอเรานกถงคาทถกสงเขาในฟงกชน จะเปนคาตวเลขของตวแปร ส าหรบในภาษา
C++ นอกเหนอจากคาของตวแปรทเราสามารถสงเขาในฟงกชนแลว คาต าแหนงหนวยความจ าของ
ฟงกชนกสามารถสงเขาในฟงกชนไดดวย ซงฟงกชนสามารถสงเปนพารามเตอรเขาในฟงกชนได
ดงนนตวชฟงกชนทรบคาต าแหนงหนวยความจ าของฟงกชนเขาไป กสามารถเรยกใชฟงกชนทสงเขา
ในฟงกชนได ซงการเรยกใชงานจะกระท าในขณะรน พารามเตอรซงเปนฟงกชนเรยกวาอารกวเมนต
ฟงกชน
ความยดหยนของตวภาษาทมอยในภาษา C + + ท าใหสามารถแกปญหาการเขยนโปรแกรมท
ซบซอนได เราสามารถเขยนฟงกชนใหสามารถรบคาตวแปรตางๆ ได ซงคาตวแปรทสงเขามา
สามารถเปลยนได นอกจากนนเรายงสามารถสงคาฟงกชนเขาในฟงกชนได ซงคาฟงกชนทสงเขาไป
กสามารถเปลยนไดเชนกน อารกวเมนตฟงกชนเปนการท างานในรปแบบตวชทชไปยงฟงกชน การ
ก าหนดตวชฟงกชน เปนดงน
ชนดขอมลทสงคากลบ (* ชอตวชฟงกชน) (ชนดขอมลของพารามเตอร);
เชน int (*func)(int, int);
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
31
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
เปนการก าหนดตวชฟงกชน (*func) มชนดขอมลการสงคากลบเปน int และมพารามเตอรเปน int
จ านวน 2 ตว ซงตวช (*func) จะชไปยงต าแหนงหนวยความจ าของฟงกชนใดๆ กได ทมชนดขอมล
การสงคากลบเปน int และการสงคาเขาในฟงกชนเปน int จ านวน 2 ตวแปร
เราสามารถใช typedef ในการก าหนดใหตวชฟงกชนสามารถน าไปสรางเปนตวแปรทเปนตว
ชฟงกชนได เชน
typedef float (*FL_FUNC)(float, float);
FL_FUNC fn1;
f n 1 เปนตวชฟงกชนทมรปแบบเดยวกนกบ F L _ F U N C ซงเราสามารถน า f n 1 ชไปยงต าแหนง
หนวยความจ าของฟงกชนใดๆ ทมรปแบบเดยวกนได หากตองการก าหนดคาเรมตนเปน NULL ให
ตวชฟงกชน กสามารถท าไดโดย
FL_FUNC fn1 = NULL;
การเรยกใชฟงกชนจะถกก าหนดในขณะคอมไพล ซงตวคอมไพลจะท าการเลอกวาฟงกชนใด
จะตองถกเรยกใชงานและก าหนดไปอยางตายตว ไมมการเปลยนแปลง แตในงานบางอยาง การ
เรยกใชฟงกชนไมสามารถก าหนดไดวาฟงกชนใดจะถกเรยกใชในขณะคอมไพล ซงการเขยน
โปรแกรมดวยภาษา C++ เราสามารถใชความสามารถทส าคญในการเรยกใชฟงกชน โดยทฟงกชน
นนจะถกเรยกใชในขณะรน ซงฟงกชนนนสามารถถกผกมดในภายหลงได (Late Binding) ฟงกชน
แบบนเรยกอกอยางวาฟงกชนคอลแบค (Callback Function)
ตวชฟงกชนกคอตวชชนดหนง เชนเดยวกนกบตวชของตวแปร ซงตวชทวไปจะชยงต าแหนง
หนวยความจ าของตวแปร และสามารถกระท ากบคาในตวแปรนนเสมอนหนงวาเปนตวแปรเดยวกน
หากเราเปนนกพฒนาทเขยนโปรแกรมดวยภาษา C + + จะตองจดจ าไวใหแมนวา โปรแกรมใดๆ ท
ก าลงท างานอย ระบบปฏบตการจะตองจดสรรพนทหนวยความจ าใหกบโปรแกรมนน ซงภายใน
โปรแกรมกประกอบไปดวย วตถ ฟงกชน และตวแปรตางๆ ดงนนเมอตวแปรสามารถอางถง
ต าแหนงหนวยความจ าได ฟงกชนกสามารถอางถงต าแหนงหนวยความจ าได เชนเดยวกน (วตถก
สามารถอางถงต าแหนงหนวยความจ าได) ทงนความสามารถในการอางถงต าแหนงหนวยความจ า
32
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ของฟงกชน จะขนอยกบภาษาทก าลงใชพฒนาอย เชนจาวาไมมความสามารถในเรองตวชฟงกชน
เมอฟงกชนถกสรางขนมาแลว ชอฟงกชนทน าหนาดวยเครองหมาย & จะหมายถง การอางอง
ต าแหนงหนวยความจ าของฟงกชนนนๆ อยางไรกตาม เราไมจ าเปนตองใชเครองหมาย & น าหนาชอ
ฟงกชนกได ใหอางถงต าแหนงหนวยความจ าของฟงกชน โดยใชชอฟงกชน และไมตองม
เครองหมายวงเลบ ( ) เชน
int average(int x, int y) {
return ((x+y)/2.0);
}
func = &average;
หรอไมจ าเปนตองใช & น าหนาชอฟงกชน func = average;
ซงเปนการก าหนดให func ชไปยงต าแหนงหนวยความจ าของฟงกชน average การอางถงต าแหนง
หนวยความจ าโดยไมใช & น าหนาฟงกชน เปนรปแบบทงาย ดงนนในต าราเลมน จะไมใช & น าหนา
ฟงกชนตลอดทงเลม ซงหมายถงการอางถงต าแหนงหนวยความจ าของฟงกชน
เมอใชตวชฟงกชน ชไปยงต าแหนงหนวยความจ าของฟงกชนใดๆ แลว เราสามารถเรยกใช
ฟงกชนโดยเรยกผานตวชฟงกชนได โดยใชรปแบบ
(*ชอฟงกชน)(พารามเตอร);
หรอ ชอฟงกชน(พารามเตอร);
เชน
กลไกการท างานในการเรยกใชฟงกชน จะกระท า ณ จดทฟงกชนนนถกเรยกใช เชน เมอเรา
int res = (*func)(10, 22);
res = func(20, 5);
เรยกใชฟงกชน average
ผานตวชฟงกชน (*func)
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
33
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ตองการเรยกใชฟงกชน d o I t ( ) เราจะตองวางฟงกชนไว ณ จดทตองการ ดงนนเมอไรกตามท
โปรแกรมถกสงใหท างาน และขนตอนการท างานมาถงจดทโปรแกรมวางไว (ในหนวยความจ า)
ฟงกชน doIt() กจะถกเรยกใช การท างานแบบนจะไมมการเปลยนแปลง ฟงกชน doIt() จะถกเรยกใช
ทกครงทการท างานมาถงจดทฟงกชน d o I t ( ) ถกเรยกใช ในบางกรณการเรยกใชฟงกชนเราไม
สามารถก าหนดไดในขณะคอมไพล ฟงกชนทถกเรยกใชอาจจะขนอยกบขอก าหนดในตวโปรแกรม
เอง หากมหลายฟงกชนทตองถกเรยกใช แตเราไมทราบวาฟงกชนใดจะถกเรยกใชจนกวาจะสงให
โปรแกรมท างาน ดงนนการเรยกใชฟงกชนโดยตรงอาจจะไมสามารถแกปญหานได แตอยางไรกตาม
เราอาจเลอกใช s w i t c h - c a s e ในการแกปญหา โดยสรางตวแปรไวเกบสถานะวาตองการเลอกใช
ฟงกชนใด จากนนจงเรยกใชฟงกชนตาม switch-case ทก าหนดไว ตวอยางท 1-7 แสดงการท างาน
ของโปรแกรมทถกเรยกใหท างานในขณะรนโดยใช switch-case
float Plus(float a, float b) {
printf("do Plus Operator\n");
return a + b;
}
float Minus(float a, float b) {
printf("do Minus Operator\n");
return a - b;
}
float Multiply(float a, float b) {
printf("do Multiply Operator\n");
return a * b;
}
float Divide(float a, float b) {
printf("do Divide Operator\n");
return a / b;
}
ตวอยางท 1-7 การเรยกใชฟงกชนในขณะรนโดยใช switch-case
34
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
void doOperatorSelection(float a, float b, char opCode) {
float result;
switch(opCode) { // execute operation
case '+' :
result = Plus(a, b);
break;
case '-' :
result = Minus(a, b);
break;
case '*' :
result = Multiply(a, b);
break;
case '/' :
result = Divide(a, b);
break;
}
printf("(%.2f, %.2f) = %.2f\n", a, b, result);
}
int _tmain(int argc, _TCHAR* argv[]) {
printf("running a doOperatorSelection\n");
doOperatorSelection(2, 5,'+');
return 0;
}
จากตวอยางท 1-7 จะเหนไดวา เราตองใช switch-case เพอท าการตรวจสอบคาในตวแปร opCode
เชนหาก opCode มคาเปน + กจะตองเรยกใชฟงกชน Plus หาก opCode มคาเปน / กตองเรยกใช
ฟงกชน Divide ซงหากตองการเพมฟงกชนเขาไปเพมมากกวาน เชน การหารหาเศษ และการยกก าลง
เปนตน เรากตองเพมค าสงในการเลอกภายใน switch-case มากกวาน ท าใหการเขยนโปรแกรมไม
เรยกใชฟงกชนค านวณโดยเรยกผาน
doOperatorSelection
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
35
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
กระชบ และเปนการเพมงานโดยไมมทสนสด เราสามารถแกปญหาการเรยกใชฟงกชน ซงถก
ก าหนดใหเรยกใชขณะรนไดโดยการใชตวชฟงกชน ท าใหเราสามารถเพมฟงกชนทมพารามเตอร
เปนตวชฟงกชน เพอใหตวชฟงกชนชไปยงฟงกชนทตองการเรยกใชงานได ดงนนหากแกไขฟงกชน
doOperatorSelection ใหเขยนเปนตวชฟงกชน จงเหลอเพยง 2 บรรทด ดงน
void callPointer2Func(float (*pt2Func)(float, float), float a, float b) {
float result = pt2Func(a, b); // call using function pointer
printf("(%.2f, %.2f) = %.2f\n", a, b, result);
}
(*pt2Func) เปนตวชทชไปยงฟงกชน ดงนนเมอมการเรยกใชฟงกชน callPointer2Func เพอก าหนด
วาฟงกชนใดจะถกเรยกใช คาพารามเตอรแรกทสงเขาในฟงกชน ca l lPo in t e r2Fun c จะตองเปน
ต าแหนงหนวยความจ าของฟงกชน และตองมชนดขอมลของการสงคากลบ และพารามเตอรใน
ฟงกชนเหมอนกน เมอตองการเรยกใชฟงกชนใดๆ กสามารถสงใหท างานไดดงน
callPointer2Func(Divide, 2, 5);
จากค าสงขางบน การอางถงฟงกชน D i v i d e โดยไมมการปอนคาและไมมเครองหมายวงเลบ ( )
หมายถงการอางถงต าแหนงหนวยความจ าของฟงกชน ดงนนคาทสงเขาในฟงกชน callPointer2Func
ตวแรก จงเปนต าแหนงหนวยความจ าของฟงกชน Divide นนเอง ซงตวชฟงกชน (*pt2Func) จะท า
การชไปยงต าแหนงหนวยความจ าของฟงกชน Divide ดงนนเมอเรยกใชค าสง pt2Func(a, b) กเสมอน
เปนการเรยกใชฟงกชน Divide นนเอง รปท 1-14 แสดงการท างานของตวชฟงกชน
void callPointer2Func(float (*pt2Func)(float, float), float a, float b) { float result = pt2Func(a, b);}
float Divide(float a, float b) { printf("do Divide Operator\n"); return a/b; }
ADDR: 0041104B
callPointer2Func(Divide, 2, 5);
รปท 1-14 การใชตวช
ฟงกชน (*pt2Func)
ชไปยง Divide
36
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
จากรปท 1-14 เมอเรยกใชฟงกชน callPointer2Func(Divide, 2, 5) ตวชฟงกชน (*pt2Func) จะชไปยง
ต าแหนงหนวยความจ า 0041104B (ยกตวอยาง) ซงเปนต าแหนงหนวยความจ าของฟงกชน Divide
ดงนนเมอเรยกใชฟงกชน p t 2 F u n c ( a , b ) จงเปนการเรยกใชฟงกชน ณ ต าแหนงหนวยความจ า
0041104B ซงกคอเปนการเรยกใชฟงกชน Divide นนเอง
การเขยนโปรแกรมในลกษณะน ท าใหเราสามารถลดค าสงในการตรวจสอบลงไปไดมาก จาก
เดมทตองเขยนเปน switch-case และเมอจ าเปนตองเขยนฟงกชนอนๆ เพมขนมา เชน การหารหาเศษ
การยกก าลง เรากไมจ าเปนจะตองมค าสงในการเลอกฟงกชนเพมเตม
ตวอยางท 1-8 การใชตวชฟงกชนเพอเรยกใชฟงกชนท าอกษรเปนตวเลกหรอตวใหญ
void doUpper(char* ch, int num) {
for(int i=0; i<num; i++) {
if(ch[i]>=0x61&&ch[i]<=0x7A)
ch[i] -= 0x20;
}
}
void doLower(char* ch, int num) {
for(int i=0; i<num; i++) {
if(ch[i]>=0x41&&ch[i]<=0x5A)
ch[i] += 0x20;
}
}
void doWordProcessing(void (*func)(char* ch, int num)) {
char ch[]={'M','a','H','a','N','a','K','o','R','n', '\0'};
func(ch, sizeof(ch) / sizeof(ch[0]));
printf("%s\n", ch);
}
int _tmain(int argc, _TCHAR* argv[]) {
doWordProcessing(doUpper);
}
ท าตวอกษรเปนตวใหญ
ท าตวอกษรเปนตวเลก
ตวชฟงกชน (*func)
เรยกใชฟงกชนผานตวช
เรยกใช doUpper
โดยผานตวชฟงกชน
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
37
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ตวอยางท 1-8 เปนการจ าลองการท างานของโปรแกรมประมวลผลค า (Word Processing) โดยใน
โปรแกรมประมวลผลค าจะตองมความสามารถในการท างานกบตวอกษรหลายอยาง เชน การแปลง
ตวอกษรใหเปนตวใหญหรอเลกทงหมด การท าตวอกษรเรมตนของประโยคใหเปนตวใหญ และการ
ตรวจสอบไวยากรณ เปนตน ซงฟงกชน doWordProcessing จะเปนตวกลางในการเรยกใชฟงกชน
เหลานน โดยตวมนท าหนาทตระเตรยมขอความใหอยในรปแบบทก าหนด จากนนกเรยกใชฟงกชนท
ตองการ ดงนนหากเขยนโปรแกรมโดยทวไปกจะตองม switch-case เพอเลอกฟงกชนทตองการให
ท างาน แตเราสามารถลดขนตอนการเขยนโปรแกรมลงไดโดยใชตวชฟงกชน ดงตวอยางท 1-8 เปน
การท าตวอกษรใหเปนตวเลกหรอตวใหญโดยการใชตวชฟงกชน (*func) ซงคาทสงเขาในฟงกชน
do Wor dP roces s ing จะตองเปนต าแหนงหนวยความจ าของฟงกชนเทานน เชน หากตองการให
เรยกใชฟงกชน doUpper กใหสงต าแหนงหนวยความจ าของฟงกชน doUpper เขาไปในฟงกชน
doWordProcessing โดยเรยกใชดงน
doWordProcessing(doUpper);
หรอ doWordProcessing(doLower);
ดงนนหากเราเพมความสามารถเขาไปในโปรแกรมประมวลค า เชน การตรวจสอบไวยากรณ โดยเพม
ฟงกชน doSpelling เขาไปในโปรแกรม ดงนนในฟงกชน doWordProcessing กไมตองมการแกไข
ใดๆ ซงการเรยกใชกสามารถท าไดโดย
doWordProcessing(doSpelling);
ความสามารถในการท างานในลกษณะนเปนสงทส าคญ ส าหรบการเขยนโปรแกรมดวย Visual C++
บนระบบปฏบตการไมโครซอฟทวนโดวส
1.8.8 ฟงกชนอนไลน (Inline Function)
กลไกการสรางชดค าสง (Execution Code) ส าหรบแตละฟงกชน ตวคอมไพลจะท าการสราง
ชดค าสงส าหรบแตละฟงกชน เมอมการเรยกใชฟงกชน การควบคมจะมาอยทฟงกชนทถกเรยกใช
38
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
จนกระทงฟงกชนนนๆ ท างานเสรจสน ฟงกชนกจะกระโดดกลบไปยงผเรยก (Caller) โดยการพอป
คาต าแหนงสงกลบ การท างานในลกษณะนท าใหโปรแกรมมขนาดเลก แตจะท าใหการเรยกใชงานชา
เนองจากตองกระโดดไปยงต าแหนงหนวยความจ าของแตละฟงกชน
จากรปท 1-15 ภายในฟงกชน main() มการเรยกใชฟงกชน func_called() กลไกการท างานจะท าโดย
กระโดดไปยง func_cal l ed( ) เมอฟงกชนทถกเรยกท างานเสรจสน การควบคมจะกลบไปยงจดท
เรยกใชฟงกชน โดยอาศยคาต าแหนงหนวยความจ าสงกลบ ทเกบไวทสแตกของฟงกชน หากมการ
เรยกใชฟงกชน ณ จดอน การท างานกจะตองกระโดดไปและกลบมายงจดเดมทกครง เนองจาก
ฟงกชนทไมใชอนไลน จะถกสรางเพยงครงเดยว
ดงนนหากตองการใหการท างานมประสทธภาพมากกวาน ในภาษา C++ สามารถท าไดโดยใช
ค าสงวน inline น าหนาชอฟงกชน เชน
ค าสงวน inline เปนการบอกใหตวคอมไพลท าการแทรกชดค าสงของฟงกชนนนๆ ในทกท ทฟงกชน
ถกเรยกใช นนกคอ จะไมมการกระโดดไปยงฟงกชนอนไลน แตจะเปนการส าเนาชดค าสงของ
ฟงกชนอนไลน ไปวางไวยงต าแหนงทถกเรยกใช ซงจะท าใหการท างานเรวมากขนกวาเดม แต
อยางไรกตาม จะท าใหไฟลของโปรแกรมมขนาดใหญขน ตวอยางกลไกการท างานของฟงกชนแบบ
อนไลน แสดงดงรปท 1-16 เมอ func_called ถกเรยกใชงาน ลงเกอร (Linker) จะท าการวางชดค าสง
(ในทนแทนดวย func_called_duty) ของฟงกชน func_called() ไวทกท ทฟงกชนถกเรยกใชงาน
func_called()
main()
func_called_dutyfunc_called_dutyfunc_called_duty
func_called()
func_called()
func_called()
รปท 1-15 กลไก
การเรยกใชฟงกชน
โดยการกระโดดไปยง
ฟงกชนทถกเรยก
เมอจบฟงกชน
การควบคมจะกลบ
มายงผเรยก
inline int MAX(int a, int b) {
return (a>b ? a : b);
}
สรางฟงกชนโดยก าหนดใหเปนอนไลน
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
39
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
main()
func_called()
func_called()
func_called()
func_called_dutyfunc_called_dutyfunc_called_duty
func_called_dutyfunc_called_dutyfunc_called_duty
func_called_dutyfunc_called_dutyfunc_called_duty
รปท 1-16 กลไกการท างาน
ของฟงกชนแบบ inline
การใชฟงกชนอนไลนเพอเพมความเรวของโปรแกรม เราควรจะใชกบฟงกชนทมขนาดเลก ม
ค าสงเพยงหนงหรอสองบรรทด และใชกบฟงกชนทตองถกเรยกใชบอยๆ จงจะท าใหฟงกชนอนไลน
เกดประโยชน หากฟงกชนทสรางขนมชดค าสงมากและซบซอน การสรางฟงกชนแบบอนไลน จะท า
ใหไฟลโปรแกรมมขนาดใหญขนมาก และความเรวในการเรยกใชฟงกชนกจะมไมมากนก
ค าแนะน า
□ เมอสรางฟงกชนโดยก าหนดใหตวฟงกชนอยภายในการประกาศคลาส ฟงกชนนนจะเปนฟงกชน
อนไลนโดยอตโนมต นกพฒนาจะไดเรยนรในหวขอการเขยนโปรแกรมเชงวตถ
□ ในการเขยนโปรแกรมดวยภาษา C และ C++ เราสามารถสรางฟงกชนขนมาไดโดยใชมาโคร เชน int MIN(int a, int b) {
return (a<b ? a : b);
}
สามารถเขยนเปนมาโครไดดงน #define MIN(a, b) (a<b ? a : b)
การท ามาโครเปนการแทน MIN(a, b) ดวย (a<b ? a : b) ดงนนหากเราเรยกใชมาโคร printf(“minimum is %d”, MIN(10, 5));
ตวประมวลผลกอน (Preprocessor) จะแทนมาโครดวยค าสงทประกาศไวในมาโคร ดงน printf(“minimum is %d”, (10<5 ? 10 : 5));
ดงนนการเขยนมาโครจงเปนการท างานในรปแบบเดยวกนกบฟงกชนอนไลน ท าใหไมตองมการ
กระโดดไปยงฟงกชนทถกเรยกใช อยางไรกตาม การใชมาโครมอนตรายในเรองการตรวจสอบชนด
40
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
ขอมล เนองจากไมมการก าหนดชนดขอมลในมาโคร ท าใหไมมการตรวจสอบชนดขอมลวาถกตอง
หรอไม ซงอาจจะท าใหโปรแกรมท างานไดผดพลาด ดงนนการใชมาโคร จงตองใชอยางระมดระวง
โดยเฉพาะชนดขอมลทสงเขาไปในฟงกชน หากไมแนใจ นกพฒนาควรจะใชฟงกชนอนไลนจะ
ปลอดภยกวา
1.8.9 ฟงกชนโอเวอรโหลด (Overloading Function)
โดยทวไป ฟงกชนทสรางขนมาจะรองรบการท างาน ตามรปแบบของฟงกชนทไดเขยนขนมา
เทานน ในภาษา C++ มความสามารถในการเพมความสามารถของฟงกชนเดม โดยสามารถสงคาเขา
ในฟงกชนไดหลากหลายรปแบบตามทไดสรางขนมา ซงกคอเราสามารถสรางฟงกชนทมชอเดยวกน
แตมพารามเตอรตางกนได พารามเตอรในฟงกชนเรยกอกอยางวาลายเซนฟงกชน (Signature Func-
t ion) ความแตกตางของลายเซนฟงกชน ไดแก จ านวนของพารามเตอร ล าดบ และชนดขอมลของ
พารามเตอร ซงจะตองไมเหมอนกนหากเปนฟงกชนโอเวอรโหลดเดยวกน เชนหากตองการสราง
ฟงกชนในการค านวณหาเลขยกก าลงของตวเลขใดๆ เราสามารถเขยนฟงกชนได ดงน
int power(int a, int n) {
int ans = 1;
for(int i=0; i<n; i++)
ans *= a;
return ans;
}
ซงเปนฟงกชนในการค านวณหาเลขยกก าลง a n โดยเปนการค านวณโดยใชชนดขอมล i n t หากเรา
ตองการเพมความสามารถของฟงกชนเลขยกก าลงใหรบพารามเตอรเปนชนดขอมล double กสามารถ
เพมฟงกชนโอเวอรโหลดไดดงน
double power(double a, double n) {
double ans = 1.0;
for(int i=0; i<n; i++)
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
41
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ans *= a;
return ans;
}
ฟงกชนโอเวอรโหลด power จงสามารถรบคาพารามเตอรทมชนดขอมลแบบ int หรอ double ได
ดงนนหากตองการสรางฟงกชนโอเวอรโหลด ฟงกชนทสรางขนมาใหมจะตองมชอเดยวกน แตม
พารามเตอรไมเหมอนกบฟงกชนทไดสรางไปแลว เชน
int power(int a, int n);
int power(int a, unsigned n);
int power(int a, short n);
double power(float a, int n);
double power(double a, int n);
double power(int a, float n);
การจบควาฟงกชนใดถกเรยกใช จะกระท าโดยตวคอมไพล และท าในขณะคอมไพล โดยพจารณา
จากชนดขอมล จ านวนพารามเตอรทตรงกนกบฟงกชนโอเวอรโหลดนนๆ
ค าแนะน า
ชนดขอมลการสงคากลบ ไมสามารถน ามาก าหนดเปนลายเซนฟงกชนได การก าหนดใหฟงกชนมชอ
เดยวกน แตมชนดขอมลการสงคากลบตางกน ไมใชฟงกชนโอเวอรโหลด ตวคอมไพลจะแจงเตอน
ขอผดพลาด หากขอก าหนดในการสรางฟงกชนโอเวอรโหลดไมถกตอง
1.8.10 ตวชชนด void (void *)
โดยทวไปตวชใดๆ จะสามารถชไปยงต าแหนงหนวยความจ าทเปนชนดเดยวกนเทานน เชน
i n t * จะตองชไปยง i n t * เทานน อยางไรกตามเราสามารถใช v o i d * เพอใหชไปยงต าแหนง
หนวยความจ าทมชนดขอมลแตกตางกน ซง v o i d * สามารถชไปยงชนดขอมลใดๆ กได หรอไม
ก าหนดชนดขอมลนนเอง ตวชชนด void (void *) เรยกวาเปนชนดขอมลสากล (Universal Type)
ดงนน
42
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
void* p;
int* a;
p = a;
a = (int *)p;
สรางตวชชนด void
สรางตวชชนด int
ให p ชไปท a
ให a ชไปท p โดยตองคาสตงกลบเปน int *
จะเหนไดวาหากสรางตวชเปนแบบ void เราสามารถน าไปชไปยงต าแหนงหนวยความจ าชนด
ใดกได ซงจะมประโยชนมากในการสรางฟงกชนทตองการรบพารามเตอรทเปนชนดขอมลแบบใดก
ได (ความสามารถนแตกตางจากฟงกชนโอเวอรโหลด) ความสามารถของฟงกชนทสามารถรบ
คาพารามเตอรเปนชนดขอมลใดๆ กไดเรยกวาความเปนทวไป (Genericness)
ตวอยางท 1-9 โปรแกรมหาความยาวของอะเรยโดยรบขอมลชนดใดกได
typedef int (*END_FN)(void* any, int index);
int arblen(void* any, END_FN is_end) {
int len = 0;
while( !is_end(any, len) )len++;
return len;
}
int int_end(int* a, int i) {
return (a[i] == -1);
}
int str_end(char* a, int i) {
return (a[i] == '\0');
}
int _tmain(int argc, _TCHAR* argv[]) {
char a[ ] = "abcdefg";
int b[ ]={0,1,2,3,4,-1};
int len = arblen(a, END_FN(str_end)); printf("length of string is %d\n", len);
len = arblen(b, END_FN(int_end)); printf("length of int array is %d\n", len);
}
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
43
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
1
ตวอยางท 1-9 เปนตวอยางโปรแกรมในการหาขนาดความยาวของอะเรย โดยท
□ พารามเตอรของฟงกชน สามารถรบอะเรยชนดใดกได เชน int char float เปนตน
□ พารามเตอรของฟงกชน เปนตวชฟงกชน
ฟงกชน arblen ใชในการค านวณหาความยาวของอะเรยโดยทไมทราบชนดขอมลของมน เพราะฉนน
arblen เปนฟงกชนหาความยาวของอะเรยทวไป (Generic Function) ตวชฟงกชน is_end ท าหนาทใน
การชไปยงฟงกชนทท าหนาทในการหาขนาดของอะเรยของชนดขอมลนนๆ โดยท าการตรวจหา
ขอมลทระบวาเปนจดสนสดของอะเรย เชน \0 ใชระบจดสนสดของชนดขอมลแบบ char และ -1 ใช
ระบจดสนสดของชนดขอมลแบบ int ซงฟงกชน arblen จะตองเรยกใชตวชฟงกชน is_end ซ าไป
จนกระทงตรวจหาจดสนสดของอะเรยพบ
จะเหนไดวาชนดขอมลทสงเขามาในฟงกชน arblen เปนแบบ void* ซงใชในการชไปยงชนด
ขอมลแบบใดกได ทยงไมทราบชนดขอมล ดงนนเราสามารถสงขอมลชนดใดๆ กไดเขาไปใน
ฟงกชน arblen
เนองจากตวชฟงกชนกเปนตวแปรแบบหนงทสามารถชไปยงฟงกชนทมรปแบบเดยวกน
(ชนดขอมลการสงคากลบ และพารามเตอรเหมอนกน) ได ดงนนเราสามารถท าคาสตงแบบชดเจน
โดยใชค าสง END_FN(str_end) เพอบงคบใหฟงกชน str_end มรปแบบเปนไปตาม END_FN ซงม
พารามเตอรเปน void* และ int
ค าแนะน า
การใชตวชฟงกชนกมขอก าหนดคลายกบการใชตวชขอมลแบบปกต โดยท ตวชจะตองมชนดขอมล
เหมอนกน (ยกเวน void*) ดงนนตวชฟงกชนทจะตองชไปยงฟงกชนใดๆ จะตองมชนดขอมลของการสง
คากลบ และพารามเตอรในฟงกชน เหมอนกนระหวางตวชฟงกชนกบฟงกชนทถกช
44
บทท 1 การเขยนโปรแกรมดวย C++ เบองตน
C+
+ C+
+
C+
+
C+
+
แบบฝกหดทายบท
1. จงอธบายขอดของภาษา C++ ทเหนอกวาภาษา C ทวไป
2. จงอธบายค าสงตอไปน วา if มการท างานหรอไม
int a = 0;
if( a = 0) printf("a=%d", a);
3. จงอธบายความแตกตางระหวางสแตกและฮพ
4. เพราะเหตใดเราจงไมสามารถสรางอะเรยทมขนาดใหญได หากตองการสราง จะตองใชเทคนคใด
5. เหตใดเราจงตองท าการคาสตงคาตวชจากฟงกชน malloc เชน a = (int *)malloc(...) จงอธบาย
6. เมอเราใชค าสงตอไปน
int *a;
a = (int *)malloc(10*sizeof(int));
สวนใดทเกบในสแตก และสวนใดทเกบในฮพ
7. จงอธบายประโยชนในการใชงานตวชแบบสองตอ (Double Pointer)
8. จงอธบายขอดของการสงคาเขาในฟงกชนโดยใชตวอางอง ทมประโยชนเหนอกวาการสงคาเขา
ฟงกชนโดยใชคา
9. จงอธบายขอแตกตางระหวางฟงกชนอนไลนและมาโคร
10. จงเขยนโปรแกรมใหสามารถเรยงขอมลไดทกชนดโดยใช void* และตวชฟงกชน
Chapter
2 บทท
เนอหาบทท 2
คลาสและการใชงาน
ฟงกชนคอนสตรคเตอรและดสตรคเตอร
คอนสตรคเตอรปรยาย
โอเวอรโหลดคอนสตรคเตอร
โอเปอเรเตอรโอเวอรโหลด
new, this, static, friend
การสบทอดของคลาส
การท าโพลมอฟซม
ฟงกชนเวอรชวล
ซปเปอรคลาสแบบนามธรรม
การเขยนโปรแกรม
เชงวตถดวยภาษา C++
46
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
วทยาศาสตรทไรศาสนา คอความพกลพการทางความคด
ศาสนาทไรวทยาศาสตร คอความมดมนอนธการของจตใจ
อลเบรต ไอนสไตน
2.1 หลกการเขยนโปรแกรมเชงวตถ
ร ปแบบการเขยนโปรแกรมแบบดงเดมเปนการแบงงานออกเปนสวนยอยหลายๆ สวน ในแตละสวนยอยกอาจแบงงานออกไปไดอก สวนยอยแตละสวนกคอโพรซเจอร ซงใชในการ
แกปญหาตามโจทยทถกก าหนดขนมา การเขยนโปรแกรมในรปแบบนเรยกวาการจ าแนกเชง
โพรซเจอร (Procedure Oriented Decomposition)
แนวคดเชงวตถ เปนรปแบบการเขยนโปรแกรมแบบใหม ทชวยใหนกพฒนาล าดบความคด
และพจารณาการสรางโปรแกรมในเชงวตถ เมอเรมสรางโปรแกรม นกพฒนาจะตองพจารณาถงตว
แปรและฟงกชนของคลาสทจะสรางขนมา อนสแตนซของคลาสคอวตถ ดงนนวตถจงสรางมาจาก
คลาสนนเอง อยางไรกตาม ตวแปรและฟงกชนในวตถทสรางมาจากคลาส อาจจะไมไดสรางขนมา
ทงหมด ขนอยกบรปแบบของการสรางคลาสนนๆ ขนมา ในแตละปญหา วตถทสรางขนมาอาจจะไม
เหมอนกน เชน ในงานดานธนาคาร วตถสามารถเปนไดตงแต บญชธนาคาร ลกคา บตรเครดต จนถง
รายการฝากถอนในแตละเดอน เปนตน วตถสามารถใชแทนสงทจบตองได หรอคดในเชงกายภาพ
เชน รายการฝากถอนในแตละเดอน หรอคดในเชงนามธรรม เชน ธรกรรม วตถทสรางขนมาจะตองม
ความสมบรณในตวเอง โดยสามารถรองรบงานทเกดขนในปญหานนๆ ได ซงการคดในเชงวตถเปน
การคดในรปแบบภาษาของปญหา (Language of Problem) ไมใชเปนปญหาของคอมพวเตอร
(Language of Computer) นนคอเมอเรานกถงการเขยนโปรแกรมเชงวตถ ตองนกถงปญหาทเกดขน
ในระบบ เชน ปญหาทเกดขนในระบบ วธการแกปญหา และตวแปรและฟงกชนทจะตองสรางขนมา
หลงจากท าความเขาใจกบเนอหาภายในบทนแลว นกศกษาจะสามารถ
□ เขาใจหลกการเขยนโปรแกรมเชงวตถดวยภาษา C++
□ น าแนวคดการเขยนโปรแกรมเชงวตถไปใชงานได
□ เรมตนการเขยนโปรแกรมดวยแนวคดเชงวตถดวยตนเองได
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
47
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
เพอแกปญหานนๆ แทนทจะเปนการคดในแบบเดม คอ จะเขยนโปรแกรมอยางไร และตองมฟงกชน
อะไรเพอแกปญหานนๆ การคดในเชงวตถ กมการแบงงานออกเปนสวนยอย โดยวตถทสรางขนมา
อาจแบงออกเปนวตถยอยๆ ลงไปอก ซงการแบงงานในลกษณะนเรยกวา การจ าแนกเชงวตถ (Object
-Oriented Decomposition) เพราะฉะนนวตถจงเปนหวใจส าคญของการเขยนโปรแกรมเชงวตถ
ในการเขยนโปรแกรมเชงวตถ สงทตองเอาใจใสคอเรองการซอนขอมล (Data Hiding) ซงเปน
การสรางฟงกชนเพอใหสามารถเรยกใชจากภายนอกและเชอมตอฟงกชนและตวแปรทเรยกใชภายใน
เทานน การก าหนดการเขาถงตวแปรและฟงกชนสามารถก าหนดไดในระหวางการสรางคลาส ตว
แปรและฟงกชนแบบ public สามารถมองไดวาเปนตวประสานแบบพบบลค (Public Interface) ของ
วตถนนๆ ตวประสานแบบพบบลคสามารถเรยกใชงานจากสวนใดของโปรแกรมกได ดงนนมนจง
เปนการก าหนดใหสวนอนของโปรแกรมสามารถใชวตถนนไดอยางไร การซอนขอมลและฟงกชน
ขางหลงตวประสานแบบพบบลค เปนเหมอนเครองมอทท างานภายในวตถ ซงภายนอกไมสามารถ
เขาถงได ดงนนแนวคดเชงวตถจงเปนการแยกงานซงตองท างานภายในวตถออกจากสวนอนของ
โปรแกรม ท าใหความซบซอนของโปรแกรมลดลงไป ดงนนตวแปรและฟงกชนทถกซอนไว ไมให
สวนอนของโปรแกรมหรอภายนอกโปรแกรมเขาถงได สามารถเปลยนแปลงแกไขโดยไมเกด
ผลกระทบกบสวนอนของโปรแกรม ตราบใดทตวประสานแบบพบบลคยงสามารถท างานแทนได
การซอนขอมลเปนแนวคดทส าคญในการเขยนโปรแกรมเชงวตถ โดยเรยกอกอยางวา การหอหม
(Encapsulation)
การออกแบบเชงวตถจะตองพจารณาถงองคประกอบอนๆ ทส าคญ ไดแก การทวตถสามารถ
น าไปใชงานไดทวไป โดยไมขนอยกบปญหาเฉพาะ ความเปนไปไดทจะขยายความสามารถของวตถ
นนๆ การน ากลบมาใชใหมของชดค าสงทมอยแลว การแกไขโดยงาย เปนตน หากนกพฒนาไดเรยนร
กลไกการท างานของหลกการเขยนโปรแกรมเชงวตถดวยภาษา C++ แลวแนวคดเชงวตถกจะเปน
รปธรรมมากขน ในปจจบนการเขยนโปรแกรมเชงวตถสามารถเขยนไดโดยตรงหรออาจแฝงอยในแต
ละภาษา ซงภาษาทนกพฒนาถกบงคบใหเขยนโปรแกรมเชงวตถโดยปรยายคอ จาวา สวนภาษา C++
นน นกพฒนาสามารถเลอกเขยนโปรแกรมเปนแบบโพรซเจอรหรอเขยนเปนเชงวตถได ซงท าใหการ
เขยนโปรแกรมส าหรบใชงานจรง ถกน าไปใชแกปญหาไดหลากหลาย เหมาะสมส าหรบแตละงาน
มากกวาภาษาจาวา เชนการเขยนในโหมด Win32 (เขยนโปรแกรมแบบโพรซเจอร) จะเหมาะสมกบ
การเขยนเกมส ในขณะทการเขยนในโหมด MFC (เขยนโปรแกรมเชงวตถ) จะเหมาะสมกบการสราง
โปรแกรมทท างานบนวนโดวส เปนตน
48
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
2.2 คลาสและการใชงาน ในการเขยนโปรแกรม เมอเรานกถงชนดขอมล เราจะนกถงชนดขอมลทแตละภาษาไดสราง
ไวให เชน integer float char double เปนตน อยางไรกตาม เราสามารถสรางวตถทไดมาจากคลาส ซง
ภายในนอกจากจะเกบตวแปรยงสามารถเกบฟงกชนไดอกดวย ตวแปรท าหนาทเกบคาพารามเตอร
ตางๆ ของวตถนน สวนฟงกชนท าหนาทในการจดการตวแปร เพราะฉะนนโดยชดเจนแลว คลาส
ประกอบดวย
□ ตวแปรสมาชก ท าหนาทในการเกบคาพารามเตอรในวตถ
□ ฟงกชนสมาชก เปนการท างานซงด าเนนการจดการตวแปรและงานตางๆ ในวตถ
คลาสเปรยบเสมอนเปนตนแบบทใชในการสรางวตถ และเปนหวใจส าคญของการเขยนโปรแกรม
เชงวตถ ซงในการเขยนโปรแกรมดวยภาษา C++ คลาสเปนชนดขอมลหนงทผใชสามารถสรางขนมา
ได ซงมขอบเขตภายในตวมนเอง ภายในคลาสประกอบไปดวย ตวแปรและฟงกชน นอกเหนอจาก
นนเรายงสามารถสราง typedef และ enum ไวภายในคลาสไดดวย อยางไรกตามคลาสตองถกนยาม
กอนทจะถกน าไปใช โดยมรปแบบดงน [3]
class { public: ... ... private: ... ... };
class
public
private
C CImage
; ส วนข
องการป
ระกาศค
ลาส
(Clas
s Dec
larati
on)
สรางไวใน
ไฟล c
lassn
ame.h
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
49
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
การประกาศคลาสมรปแบบโดยใชชอคลาสน าหนาดวย C ตวใหญ (เปนรปแบบเฉพาะในการก าหนด
คลาสใน Visual C++) สวนตวคลาสเปนการก าหนดสมาชกภายในคลาส โดยมรปแบบดงน
□ ตวแปรสมาชกภายในคลาสมการประกาศเหมอนกบตวแปรทวไป แตไมสามารถก าหนดคา
เรมตนได ในขนตอนการประกาศ เชน
□ ฟงกชนสมาชกถกประกาศโดยมรปแบบเดยวกนกบโปรโตไทปของฟงกชน ซงตองประกาศไว
ภายในคลาส และสวนการท างานของฟงกชนจะตองก าหนดไวทสวนอนของโปรแกรม หากสราง
ฟงกชนทมรปแบบทสมบรณไวภายในตวคลาส ฟงกชนนนจะถกก าหนดใหเปนอนไลนฟงกชน
โดยอตโนมต (ควรจะสรางฟงกชนทสมบรณไวในตวคลาส เฉพาะฟงกชนทมขนาดเลก และม
ค าสงไมมากเทานน เชน ฟงกชนในการสงคากลบ เปนตน)
ชอคลาสเรยกอกอยางวาปายประกาศคลาส (Class Tag) สมาชกของคลาสทเปนตวแปรและฟงกชน
จะมขอบเขตภายในคลาส ซงสมาชกทสรางขนภายในคลาสจะสามารถถกเรยกใชไดภายในคลาส
เทานน ไมสามารถอางถงจากภายนอกไดโดยตรง โดยไมผานคลาสหรอวตถ สมาชกของคลาสทมชอ
เดยวกน แตอยตางคลาสกน กจะถอวาไมใชตวเดยวกน เมอคลาสไดถกสรางขนมาแลว คลาสสามารถ
ใชในการสรางวตถ หรออนสแตนซของคลาสได ดงนนสามารถมองไดวาคลาสเปนตนแบบเพอใช
ในการสรางวตถนนเอง วตถแตละอนทถกสรางขนมาจะเปนอสระตอกน และมหนวยความจ าเปน
ของตนเอง (หนวยความจ าของตวแปรและฟงกชน) อยางไรกตามวตถทสรางมาจากคลาสตนแบบ
เดยวกน จะใชฟงกชนรวมกน แตมหนวยความจ าทใชเกบตวแปรเปนของแตละวตถ แยกจากกน วธน
ชวยใหประหยดพนทหนวยความจ าทตองการใชในการสรางวตถ
ฟงกชนสมาชกของคลาส สามารถเขยนไวภายในคลาส (เปนฟงกชนอนไลน) หรอเขยนไว
ภายนอกหลงจากประกาศคลาสไปแลวกได ซงโดยทวไปคลาสจะถกแยกออกเปนสองไฟล คอสวน
class CMyClass {
int x;
float r = 2.35;
};
ถกตอง
ผดพลาด ประกาศแลวก าหนดคาเรมตน
50
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
การประกาศคลาส จะเกบไวทไฟลสวนหว (Header File) มนามสกลเปน .h และไฟลสวนตวฟงกชน
มนามสกลเปน .c p p ซงไฟลนามสกล .c p p จะใชในการเกบสวนตวฟงกชน ซงเปนสวนทท าให
เกดผล (Implementation) มรปแบบดงน
ชนดขอมล ชอคลาส :: ชอฟงกชน ( ) {
สวนตวฟงกชน
}
อยางไรกตาม ในสวนของการสรางฟงกชนสมาชกของคลาส สามารถเขยนไวในไฟลเดยวกน
หรอแยกกนกบสวนของการประกาศคลาสกได ดงตวอยางท 2-1 เปนการประกาศคลาส CEmployee
จากนนสรางสวนการท างานของฟงกชนไวภายนอกซงเปนฟงกชนสมาชกของคลาส CEmployee ซง
มทงหมด 4 ฟงกชนดวยกน แตละฟงกชนท าหนาทในการเขาถงตวแปรสมาชกของคลาส
class CEmployee {
public:
CEmployee(string theName, float thePayRate);
string getName() const;
float getPayRate() const;
float pay(float hoursWorked) const;
private:
string name;
float payRate;
};
CEmployee::CEmployee(string theName, float thePayRate) {
name = theName;
payRate = thePayRate;
}
ตวอยางท 2-1 การประกาศคลาสและสวนการท างานของฟงกชน
ใชค าสงวน const เพอ
ก าหนดใหคาทสงกลบ
เปนคาคงท
สวนของการเขยนค าสงของคลาส
(Class Implementation) สรางไว
ในไฟล classname.cpp
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
51
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
string CEmployee::getName() const {
return name;
}
float CEmployee::getPayRate() const {
return payRate;
}
float CEmployee::pay(float hoursWorked) const {
return hoursWorked * payRate;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
CEmployee empl("John Burke", 25.0);
cout << "For Employee:" << endl;
cout << "Name: " << empl.getName().c_str() << endl;
cout << "Pay: " << empl.pay(40.0) << endl;
}
คลาสหอหมสมาชกของคลาสและควบคมการเขาถงจากภายนอก เพราะฉะนน คลาสอาจมอง
ไดวาเปนหนวยของขอมลทซอนไวและการควบคมการเขาถง การเขาถงสมาชกภายในคลาสสามารถ
ท าไดหรอไมขนอยกบขอก าหนดในการเขาถงของคลาสนน ถาสมาชกของคลาสถกก าหนดใหเขาถง
ได การเขาถงสมาชกจะกระท าผานอนสแตนซของคลาส
สมาชกของคลาสสามารถก าหนดใหเปนแบบ private protected และ public ไดโดย [4]
□ private เปนสมาชกทสามารถเขาถงได หรอเรยกใชงานไดเฉพาะสมาชกของคลาสนนๆ เทานน
คลาสหรอฟงกชนภายนอกไมสามารถเขาถงได สมาชกแบบ p r i v a t e เปนการซอนขอมลและ
ฟงกชนไวภายในวตถ
□ public เปนสมาชกทสามารถเขาถงได หรอเรยกใชงานไดทกทของโปรแกรม ตวแปรและฟงกชน
แบบ public เปนเสมอนตวเชอมตอกบภายนอก ซงเปนสวนทวตถถกเรยกใช
52
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
□ protected เปนสมาชกทสามารถเขาถงได หรอเรยกใชงานไดเฉพาะสมาชกของคลาสนนๆ และ
สบคลาสเทานน ภายนอกคลาสหรอฟงกชนภายนอกไมสามารถเขาถงได ดงนนสมาชกแบบ pro-
tected จงเปนการปกปองขอมลและฟงกชนใหใชงานไดภายในคลาสและสบคลาสนนเอง
โดยปกต หากไมก าหนดรปแบบการเขาถง ตวแปรและฟงกชนจะเปนแบบไพรเวทโดยปรยาย
อยางไรกตาม เราควรก าหนดการเขาถงสมาชกใหชดเจน ซงเปนรปแบบการเขยนโปรแกรมทด
ภาษา C + + มระดบของการปกปองตวแปรและฟงกชนสมาชกภายในคลาส ตวแปรและ
ฟงกชนสมาชกแบบ p r i v a t e ไมสามารถเขาถงไดจากฟงกชนอนๆ ซงไมไดเปนสมาชกของคลาส
นนๆ ระดบตอไปของการปกปองคอ protected ตวแปรและฟงกชนสมาชกแบบ protected สามารถ
เขาถงไดจากสมาชกของคลาส และจากคลาสทสบทอดมาจากคลาสนนๆ ระดบของการปกปองนอย
ทสดคอ public ตวแปรและฟงกชนสมาชกแบบ public สามารถเขาถงไดจากฟงกชนใดๆ กได ซงเปน
ตวประสานเพอใหภายนอกสามารถเรยกใชงานได ระดบการปกปองแสดงดงรปท 2-1
ท าไมตองก าหนดตวแปรสมาชกเปนแบบ private
ตวแปรสมาชกแบบ private สามารถเขาถงไดจากสมาชกของคลาสไดเทานน หรอกลาวไดอก
อยางวาภายนอกไมสามารถเขาถงสมาชกแบบ private ได (ยกเวนการก าหนดใหฟงกชนหรอคลาส
เปนเพอน (f r i e n d ) ซงจะไดกลาวถงตอไป) ดงนนจงตองมฟงกชนสมาชกแบบ p u b l i c เปนตว
รปท 2-1 ระดบการ
ปกปองขอมล
สามระดบคอ
private protected
และ public
private:public:
protected:
private protected
protected:public:
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
53
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
ประสานเพอใหสามารถเขาถงตวแปรและฟงกชนสมาชกแบบ private ได เชนตวแปร nSalary ใชเกบ
เงนเดอนของพนกงาน ดงนนควรเปนตวแปรสมาชกแบบ private จากนนจงสรางฟงกชนแบบ public
เพอใชในการก าหนดคาหรอดงคาจากตวแปร nSalary เชน getSalary และ setSalary อนจะท าใหคา
ในตวแปร nSalary ถกตรวจสอบความถกตองและความเขากนไดของขอมล (Data Validation and
Integrity) เสมอ อยางไรกตามเราไมจ าเปนตองสรางฟงกชนส าหรบตวแปรแบบ private ทกตวเสมอ
ไป ขนอยกบความเหมาะสมและความจ าเปนของงาน
ในการเขยนโปรแกรมทด เราควรแยกกนระหวางกฎในการใชงานคลาส (ตวประสานแบบ
พบบลค) และรายละเอยดของงานภายในคลาสนน ใหมากทสดเทาทจะท าได ดงนน
□ กฎในการใชงานคลาส คอฟงกชนสมาชกทเปนแบบ p u b l i c สามารถเรยกใชจากภายนอกได
ดงนนมนจงเปนการก าหนดรปแบบการใชงานของคลาสนนเอง
□ รายละเอยดของงานภายในคลาส คอฟงกชนสมาชกแบบ private ซงถกเรยกใชโดยสมาชกภายใน
คลาสไดเทานน ดงนนมนจงเปนสวนของงานภายในคลาส ทถกปกปองจากภายนอก
เพราะฉะนนรปแบบการสรางคลาสทด ควรเปนดงน
□ ก าหนดใหตวแปรสมาชกเปนแบบ private ทงหมด
□ สรางฟงกชนเพอเขาถงตวแปรสมาชกแบบ private ใหเพยงพอ (get และ set)
□ ฟงกชนทสนบสนนการท างานภายในคลาสใหก าหนดเปนแบบ private
ดงนนชนดของฟงกชนมสามแบบดงน
□ ตวเขาถง (Accessor) คอฟงกชนสมาชกทสงคากลบตวแปรทก าหนด โดยทไมมการเปลยนแปลง
คานนๆ เชน ฟงกชน getDate เปนตน
□ ตวเปลยนคา (Mutator) เปนฟงกชนสมาชกทเปลยนคาตวแปรในคลาส เชน ฟงกชน setPayRate
□ คอนสตรคเตอร (Cons t ruc to r ) เปนฟงกชนทมชอเดยวกนกบคลาส โดยมนจะถกเรยกใชโดย
อตโนมตเมออนสแตนซของคลาสถกสรางขนมา
54
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ตวแปรและฟงกชนสมาชกแบบ public จะไมไดถกก าหนดใหเปน public โดยอตโนมตเมอสบทอด
ไปยงสบคลาส เราตองท าการก าหนดโดยชดเจนใหมการสบทอดแบบ p u b l i c จงจะท าใหตวแปร
เปนไปตามทก าหนดในซเปอรคลาส
ฟงกชนและคลาสภายนอกทไมใชสมาชกของคลาส สามารถเขาถงตวแปรและฟงกชนของ
คลาสทเปนแบบ private และ protected ได โดยการใชค าสงวน friend ซงจะท าใหเราสามารถเรยกใช
ตวแปรและฟงกชนสมาชก ทเปนแบบ private และ protected โดยขามขอก าหนดในเรองการหอหม
นกพฒนาจะไดเรยนรการสบทอดและการใชค าสงวน f r i end ในทายบท สทธในการเขาถงสมาชก
ของคลาสแสดงดงตารางท 2-1 โดยถาเปนสมาชกภายในคลาสเดยวกนสามารถเขาถงไดทกระดบ ถา
เปนสมาชกของสบคลาสสามารถเขาถงไดเฉพาะ public และ protected และถาไมไดเปนสมาชกของ
คลาสจะสามารถเขาถงไดเฉพาะสมาชกแบบ public เทานน
ตารางท 2-1 สรปการเขาถงสมาชกของคลาส
เมอคลาสไดถกประกาศขนมาแลว เราสามารถสรางวตถไดโดยมรปแบบดงน
การก าหนดในแบบแรกเปนการสรางวตถ โดยวตถทถกสรางจะเกบไวทสแตก สวนแบบทสองเปน
การขอจองหนวยความจ าโดยใชตวด าเนนการ n e w โดยพนทหนวยความจ าทขอจองไดจะเทากบ
ขนาดของคลาส การประกาศในรปแบบนจะมการด าเนนการสองขนตอน คอ
□ สรางอนสแตนซ (Instantiation) โดยการจองหนวยความจ า
□ การก าหนดคาเรมตน (Initialization) ใหกบสมาชกของคลาส
การเขาถง public protected private
สมาชกภายในคลาสเดยวกน ได ได ได
สมาชกของสบคลาส ได ได ไมได
ไมใชสมาชกของคลาส ได ไมได ไมได
ชอคลาส ตวแปร;
ชอคลาส* ตวแปร = new ชอคลาส;
สรางวตถไวทสแตก
สรางวตถไวทฮพ
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
55
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
เชน
CEmployee empl("John Burke", 25.0);
เปนการสรางอนสแตนซของคลาส CEmployee ชอ empl โดยท าการปอนคาพารามเตอรสองตว เปน
ขอความและตวเลข เมอสรางอนสแตนซของคลาสไดแลว เราสามารถเรยกใชฟงกชนของวตถผานตว
ด าเนนการ . ไดดงน
cout << "Pay: " << empl.pay(40.0) << endl;
ซงเปนการเรยกใชฟงกชน pay โดยสงคา 40.0 เขาในฟงกชน ผานวตถชอ empl
รปท 2-2 เปนภาพรวมการสรางคลาสและการสรางอนสแตนซของคลาส (วตถ) โดยคลาส
CEmployee มฟงกชนสมาชกอยท งหมดสฟงกชน เปนแบบ public และมตวแปรสมาชกอกสองตว
เปนแบบ private ดงนนเมอคลาสถกสรางเปนวตถโดย CEmployee empl("John Burke", 25.0)
ฟงกชนและตวแปรสมาชกทงหมดทไมใชแบบสแตตก จะถกสรางไวในวตถชอ e m p l คณสมบต
ตางๆ กจะเปนไปตามรปแบบทก าหนดไวในคลาส CEmployee เมอสรางวตถแลว ฟงกชนคอนสตรค
รปท 2-2 การสราง
อนสแตนซของคลาส
empl("John Burke", 25.0);
CEmployee
private:
name payRate
private:
name payRate
empl.pay(40.0)
empl.payRate = 10;
public: CEmployee() getName() getPayRate() pay()
public: CEmployee(string theName, float thePayRate) getName() getPayRate() pay(float hoursWorked)
56
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
เตอรจะถกเรยกใชงานโดยอตโนมต ดงนน "John Burke" จะถกส าเนาไปไวในตวแปร theName และ
จะถกถายคาไปเกบไวท name หากเราเรยกใชฟงกชน pay ผานวตถ empl ดวยค าสง empl.pay(40.0)
จงเปนการเรยกใชฟงกชนทอยในวตถ empl ไมใชฟงกชนทอยทคลาส CEmployee หากตวแปรหรอ
ฟงกชนสมาชกไดถกก าหนดใหเปนแบบ private เราจะไมสามารถเขาถงสมาชกนนไดโดยตรง เชน
หากเรยกใชค าสง empl.payRate = 10 จะเกดขอผดพลาดขนมา เนองจากเปนการเรยกใชตวแปร
payRate ซงไมสามารถเขาถงไดจากภายนอก
2.3 ฟงกชนคอนสตรคเตอรและดสตรคเตอร
เมอเราตองการเขยนค าสงใหท างานทกครงทวตถถกสรางและวตถถกท าลาย เชน การจอง
หนวยความจ าใหกบตวแปรสมาชก ทตองกระท าทกครงทเรมตนสรางวตถ หรอการก าหนดคาเรมตน
ใหกบตวแปรสมาชก เราสามารถใสค าสงเหลานนไวทฟงกชนคอนสตรคเตอรได และหากตองการ
ใหค าสงใดๆ มการท างานทกครงทวตถโดนท าลาย กสามารถใสค าสงไวในฟงกชนดสตรคเตอรได
□ ฟงกชนคอนสตรคเตอร จะถกเรยกใชครงแรกและครงเดยวเมอวตถถกสรางขนมา
□ ฟงกชนคอนสตรคเตอร ตองมชอเดยวกนกบคลาส
□ ฟงกชนคอนสตรคเตอร ไมมการสงคากลบ
ยกตวอยางเชน หากเราตองการสรางคลาสเกบขอมล บญชธนาคาร ซงมตวแปรสมาชก balance และ
interest_rate เราสามารถสรางฟงกชนคอนสตรคเตอร ไวภายในคลาส CBankAccount ไดดงน
class CBankAccount {
public:
CBankAccount(int dollars, int cents, double rate);
private:
double balance;
double interest_rate;
};
CBankAccount::CBankAccount(int dollars, int cents, double rate) {
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
57
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
balance = dollars + 0.01*cents;
interest_rate = rate;
}
สงเกตวาฟงกชนคอนสตรคเตอร CBankAccount ไมมการสงคากลบ โดยไมตองมแมกระทงค าสงวน
v o id น าหนาชอฟงกชน หากตองการสรางวตถโดยมการสงคาเขาไปยงฟงกชนคอนสตรคเตอรของ
คลาส สามารถท าไดโดย
CBankAccount acc1(10,50,2.0);
CBankAccount acc2(500,0,4.5);
CBankAccount acc1(10,50,2.0) เปนการสรางวตถ โดยท าการสงคาเขาในฟงกชนคอนสตรคเตอร
ตวคอมไพลจะท าการหาฟงกชนคอนสตรคเตอรทมพารามเตอรตรงกน จากนนจงเรยกใชฟงกชน
คอนสตรคเตอรนนๆ ดงนนเมอประกาศสรางวตถตามตวอยางขางบนแลว ฟงกชนคอนสตรคเตอร
CBankAccount(int dollars, int cents, double rate) จะถกเรยกใชงานโดยอตโนมต ฟงกชนคอนสตรค
เตอรไมสามารถเรยกใชงานไดโดยตรงแบบฟงกชนทวไป ดงนน
จงไมสามารถท างานได
เมอตองการใหชดค าสงใดๆ ท างานเมอวตถโดนท าลาย สามารถท าไดโดยสรางฟงกชนด
สตรคเตอร โดย
□ ฟงกชนดสตรคเตอร จะถกเรยกใชครงแรกและครงเดยวเมอวตถโดนท าลาย
□ ฟงกชนดสตรคเตอร ตองมชอเดยวกนกบคลาส และน าหนาดวยเครองหมาย ~
□ ฟงกชนดสตรคเตอร ไมมการสงคากลบ
acc2.CBankAccount(23, 2, 3); ผดพลาด
58
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ซงโดยทวไป จะใสชดค าสงทตองการยกเลกการจองหนวยความจ า หรอคนทรพยากรใหแกระบบ ไว
ในฟงกชนดสตรคเตอร ดงนนเมอวตถโดนท าลาย ค าสงตางๆ ทใชในการคนทรพยากรใหแก
ระบบปฏบตการ กจะถกเรยกใชงานโดยอตโนมต ซงเปนรปแบบการเขยนโปรแกรมทปลอดภย
ดงนนฟงกชนคอนสตรคเตอร มไวส าหรบท างานโดยอตโนมตเมอวตถถกสราง เชน การจอง
หนวยความจ า การก าหนดคาเรมตนใหตวแปรสมาชก การเปดไฟล การสรางเมน เปนตน และ
ฟงกชนดสตรคเตอรท างานเมอวตถโดนท าลาย เชน การยกเลกการใชหนวยความจ า การปดไฟลหรอ
สตรม การลบไฟลชวคราว การคนทรพยากรณตางๆ ใหกบระบบปฏบตการ เปนตน วงจรชวตของ
วตถแสดงดงรปท 2-3
class CRectangle {
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};
CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}
CRectangle::~CRectangle () {
delete width;
delete height;
}
ฟงกชนคอนสตรคเตอร
ฟงกชนดสตรคเตอร
ท างานครงแรกครงเดยว
เมอวตถถกสราง
ท างานเมอวตถโดนท าลาย
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
59
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
รปท 2-3 วงจรชวต
ของวตถ
2.4 คอนสตรคเตอรปรยาย (Default Constructor)
โดยปกตเมอเราประกาศคลาสขนมา หากไมมการสรางฟงกชนคอนสตรคเตอร ตวคอมไพล
จะท าเสมอนวามคอนสตรคเตอรโดยปรยายซงไมมการสงคาเขาในฟงกชน ดงนนหากมการประกาศ
คลาส
class CDefCon {
public:
int x;
int y;
};
ตวคอมไพลกจะสรางคอนสตรคเตอรขนมาใหโดยปรยาย เพราะฉนนเราสามารถสรางอนสแตนซ
ของคลาสขนมาได โดย
CDefCon def;
จะสามารถสรางวตถได อยางไรกตาม เมอเราสรางฟงกชนคอนสตรคเตอรขนมาเองแลว ตวคอมไพล
จะไมสรางคอนสตรคเตอรปรยายอกตอไป ดงนนหากมการสรางฟงกชนคอนสตรคเตอรเพมโดยรบ
60
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
คาสองพารามเตอร
class CDefCon {
public:
int x;
int y;
CDefCon(int a, int b){x=a; y=b;}
};
เราตองสรางวตถโดยก าหนดพารามเตอรสองตว ดงนน
CDefCon def(2, 3);
จงเปนการสรางวตถไดถกตองตามรปแบบของคลาส CDefCon แต
CDefCon def;
ไมสามารถท างานได เนองจาก CDefCon ไมมฟงกชนคอนสตรคเตอรทไมมพารามเตอร และเราได
สรางฟงกชนคอนสตรคเตอรทบคอนสตรคเตอรปรยายไปแลว
นอกเหนอจากนน ตวคอมไพลยงไดสรางฟงกชนพเศษ ท าหนาทในการส าเนาวตถ ซงเรยกวา
คอนสตรคเตอรส าเนา (Copy Constructor) ดงนนเราสามารถสรางอนสแตนซของคลาสโดยการท า
ส าเนามาจากวตถอนได เชน
CDefCon def1(2, 3);
CDefCon def2(def1);
ซงตวคอมไพลจะสรางฟงกชนใหโดยนย มรปแบบดงน
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
61
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
CDefCon(const CDefCon& c) {
x = c.x;
y = c.y;
}
2.5 โอเวอรโหลดคอนสตรคเตอร (Overloading Constructors)
ฟงกชนคอนสตรคเตอร สามารถท าเปนฟงกชนโอเวอรโหลดได เชน
class CBankAccount {
public:
CBankAccount();
CBankAccount(int dollars, int cents, double
rate);
CBankAccount(int dollars, int cents);
};
CBankAccount::CBankAccount(){
balance = 0.0;
interest_rate = 0.0;
}
CBankAccount::CBankAccount(int dollars, int
cents){
balance = dollars + 0.01*cents;
interest_rate = 0.0;
}
CBankAccount::CBankAccount(int dollars, int
cents, double rate){
balance = dollars + 0.01*cents;
interest_rate = rate;
}
62
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ดงนนเมอมการสรางวตถ ตวคอมไพล จะท าการจบคฟงกชนคอนสตรคเตอร และจะเรยกใชฟงกชน
คอนสตรคเตอรทมพารามเตอรตรงกน ใหท างานตามพารามเตอรทปอนเขาไป
หากตองการก าหนดคาเรมตนใหกบตวแปรสมาชก เราไมสามารถก าหนดไดตงแตเรมสรางตว
แปร ดงนนการก าหนดคาเรมตนทเหมาะสมจงควรจะกระท าทฟงกชนคอนสตรคเตอร เชน
คาเรมตนควรจะก าหนดในฟงกชนคอนสตรคเตอร ซงเปนประโยชนทส าคญของฟงกชนคอนสตรค
เตอร ดงนนการก าหนดคาเรมตนทถกตองควรจะเขยนค าสงดงน
CDate::CDate(unsigned m = 1, unsigned d = 1, unsigned y = 1955)
: month(m), day(d), year(y) {
…
}
การถายคา month(m) เปนการก าหนดคาใหตวแปรสมาชก ซงเปนรปแบบการก าหนดคาคอนสตรค
เตอร (Constructor Initialization) ในพารามเตอรของฟงกชน การก าหนดให unsigned m = 1 เปนการ
ก าหนดให m มคาเปน 1 หากไมมการปอนคาพารามเตอรเขาในฟงกชน ดงนน
CDate dd1;
class CDate {
public:
…
private:
unsigned month = 1;
unsigned day = 1;
unsigned year = 2002;
};
ผดพลาด ก าหนดคาไมได
ผดพลาด ก าหนดคาไมได
ผดพลาด ก าหนดคาไมได
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
63
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
จงเทาเทยมกนกบ
CDate dd2(1, 1, 1955);
CDate dd3(1, 1);
ดวยเทคนคการเขยนโปรแกรมแบบน ท าใหเราสามารถสรางฟงกชนคอนสตรคเตอรเพยงหนง
ฟงกชน แตสามารถท างานไดตงแตศนยจนถงสามพารามเตอร
2.6 การสรางวตถโดยใชตวด าเนนการ new
ในกรณทตองการสรางวตถโดยใหจองหนวยความจ าโดยใชตวด าเนนการ new สามารถท าได
โดยใชรปแบบดงน
ชอคลาส* ตวแปร = new ชอคลาส(พารามเตอร);
ยกตวอยางเชน
CBankAccount* acc4 = new CBankAccount;
CBankAccount* acc5;
acc5 = new CBankAccount;
การสรางวตถโดยไมใชตวด าเนนการ new วตถจะถกสรางขนมา แลวเกบไวทสแตก ดงเชนการ
ประกาศตวแปรแบบทวไป ดงนนหากตองการสรางวตถจ านวนมากๆ เราไมสามารถสรางไดโดย
ใชอะเรย เชน
CBankAccount account[1000000];
เปนการสรางอะเรยจ านวน 1,000,000 หนวยขอมล ซงไมสามารถเกบลงในสแตกไดอยางเพยงพอ
ดงนนโปรแกรมสามารถคอมไพลได แตหากสงใหโปรแกรมท างาน จะเกดขอผดพลาดในการใชงาน
64
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
สแตก ดงนนหากตองการแกปญหาการสรางวตถจ านวนมาก หรอไมทราบจ านวนวตถทจะถกสราง
อยางแนนอน เชนวตถทเปนตวละครในเกมส วตถทเปนรปทรงตางๆ ในโปรแกรม Visio ซงวตถ
เหลานนจะไมทราบจ านวนทแนนอนทจะถกสราง ดงนนวตถควรจะถกสรางในขณะรน และเรา
สามารถสรางวตถไดจ านวนมากตามทตองการ ตราบใดทฮพยงมพนทวางใหใชงานได ดงนน
CBankAccount* pAcc;
for(int i=0; i<1000000; i++) {
pAcc = new CBankAccount;
printf("Object has been created!\n");
delete pAcc;
printf("Object has been destroyed!\n");
}
เปนการสรางวตถจ านวน 1,000,000 หนวยขอมล โดยการใชตวด าเนนการ new จากนนเมอท างาน
เสรจสนแลว ใหท าลายวตถโดยใชตวด าเนนการ delete ตวช pAcc จะถกสรางไวทสแตก เมอสราง
วตถโดยใชตวด าเนนการ n e w วตถจะถกสรางไวทฮพ ซงเปนหนวยความจ าสวนทเหลอทไมไดใช
งาน ท าใหเราสามารถใชหนวยความจ าไดมากเทาทตองการ ตราบใดทยงมหนวยความจ าเหลออย
รปแบบการจองหนวยความจ าแสดงดงรปท 2-4
สรางตวช pAcc
สรางวตถโดยใชตวด าเนนการ new
ท าลายวตถโดยใชตวด าเนนการ
delete
รปท 2-4 การสราง
วตถดวยวธการสราง
แบบอะเรยและแบบ
ใชตวด าเนนการ new
CBankAccount account[1000000];
account 1,000,000
CBankAccount* pAcc;
pAcc
CBankAccountfor(int i=0; i<1000000; i++) { pAcc = new CBankAccount; ... delete pAcc;}
new
delete
pAcc
………...
1
2
อนง ต าแหนงหนวยความจ าทขอจอง จะไมเรยง
ตอเนองกน โดยต าแหนงทขอจองได จะขนอยกบ
พนทวางในหนวยความจ า
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
65
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
ประโยชนของการสรางวตถในรปแบบทใชตวด าเนนการ new ในการสราง คอตองการสรางวตถโดย
ทไมทราบจ านวนของวตถทตองการจะสราง (หากใชอะเรย จะตองก าหนดขนาดของอะเรย ซงจะม
ขนาดตายตว ไมสามารถเปลยนแปลงไดในขณะรน) และการสรางวตถมจ านวนมาก ซงสแตกไม
สามารถรองรบไดเพยงพอ
ขอควรระวง
จากตวอยางวธการสรางวตถในรปท 2-4 เปนการจองหนวยความจ าซ าๆ กนหลายครง ดงนน ในการขอ
ใชหนวยความจ าแตละครงโดย pAcc = new CBankAccount เปนการสรางวตถและจองหนวยความจ า
แลวให pAcc ชไปยงต าแหนงหนวยความจ าของวตถนน ดงนน ต าแหนงหนวยความจ าเดมท pAcc ชอย
กจะเปลยนไปยงต าแหนงหนวยความจ าใหม ซงต าแหนงหนวยความจ าเดมของวตถกจะไมมตวชใด ชไป
ยงต าแหนงหนวยความจ านนอก ท าใหเกดหนวยความจ ารวไหล (Memory Leak) ในการน าไปใชงานจรง
ตองมตวชทท าหนาทในการชไปยงต าแหนงหนวยความจ าของวตถทไดสรางขนมา ซงโดยทวไปจะมกา
ร
ใชโหนดในลงคลสต ในการเกบต าแหนงหนวยความจ าของวตถ ดงนนตวอยางในรปท 2-4 ขอให
นกพฒนาใชอยางระมดระวง
2.7 โอเปอเรเตอรโอเวอรโหลด
ในการเขยนโปรแกรมดวยภาษา C++ เราสามารถสรางฟงกชนทมชอเดยวกน แตมจ านวน
พารามเตอรตางกน เรยกวา ฟงกชนโอเวอรโหลด ซงตวคอมไพลจะถอวาฟงกชนเหลานนแตกตางกน
เนองจากมพารามเตอรตางกน ท าใหเกดความสะดวกเมอน าไปใชงาน นกพฒนาสามารถเรยกใช
ฟงกชนชอเดยวกน แตก าหนดคาพารามเตอรตางกนได โดยทไมตองจ าชอทแตกตางกน
ในการเขยนโปรแกรมดวยภาษา C++ ตวแปรของคลาสจะถกหอหมไวในคลาส เมอน าคลาส
มาสรางเปนวตถ แลวตองการน าคาในตวแปรของแตละวตถรวมกน เชน
CString s1,s2, s3;
s1 = "This is ";
s2 = "a Test";
s3 = s1 + s2;
ซงเปนการเกบคาสตรงลงใน s1 และ s2 จากนนน ามารวมกนโดยใชตวด าเนนการ + ซงเปนการน า
66
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
สตรงใน s1 และ s2 มารวมกน (ในทนเปนสตรง "This is " และ "a Test") จากนนจงท าการถายคาลง
ใน s3 จะเหนไดวา s3 = s1 + s2 เปนการอางถงวตถ แตในการด าเนนการจรงเปนการน าสตรงมา
รวมกน กลไกการท างานแบบน เปนความสามารถในภาษา C++ ซงจะชวยเพมความสะดวกในการ
เขยนโปรแกรม และการเรยกใชงาน
ในภาษา C++ เราสามารถสรางโอเวอรโหลดโอเปอเรเตอรตางๆ ได เชน + - * / >= ++ [ ] เปน
ตน ซงเปนตวด าเนนการทางคณตศาสตรส าหรบวตถ สามารถท าไดโดยสรางฟงกชนโอเปอเรเตอร
(Opera to r Func t ions ) ซงชวยใหการเขยนโปรแกรมเชงวตถสะดวกมากยงขน โดยการสรางตว
ด าเนนการทางคณตศาสตรท าใหสามารถใชตวด าเนนการ เชน + - ไดกบชนดขอมลพนฐาน (เชน int
float long char) และอนสแตนซของคลาส เพราะฉะนนเราสามารถสรางฟงกชนโอเวอรโหลด ท
สามารถท างานไดกบตวด าเนนการทางคณตศาสตรทวไปได นอกเหนอจากนนเราสามารถสรางตว
ด าเนนการรบเขา/สงออก เชน << >> ส าหรบวตถ ซงสามารถท างานไดกบการรบเขาและการสง
ขอมลออกทฮารดแวรไดทวไป รปแบบการก าหนดโอเวอรโหลดโอเปอเรเตอร เปนดงน
ค าสงวน operator ตองใชทกครงทตองการสรางโอเวอรโหลดโอเปอเรเตอร op เปนสวนของการ
ก าหนดตวด าเนนการทางคณตศาสตร ในการสรางโอเวอรโหลดโอเปอเรเตอร ชองวางระหวาง
operator กบ op จะมหรอไมกได เชน operator+ หรอ operator + ขนอยกบความสะดวกในการเขยน
โปรแกรมในแตละงาน โอเปอเรเตอรทสามารถโอเวอรโหลดไดแสดงดงตารางท 2-2
การท าโอเวอรโหลดโอเปอเรเตอร ไมไดเปนการเพมความสามารถใหโปรแกรมทเขยนดวย
ภาษา C + + ฟงกชนทเขยนเปนแบบโอเวอรโหลดโอเปอเรเตอร สามารถเขยนไดดวยฟงกชนแบบ
ปกต อยางไรกตาม หากเขยนฟงกชนเปนแบบโอเวอรโหลดโอเปอเรเตอร จะท าใหการเขยนค าสง
:: operator op( )
operator
+ - * / << >>
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
67
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
เพอรองรบการท าตวด าเนนการทางคณตศาสตรงายกวาเขยนดวยฟงกชนปกต อกทงจะท าใหผท
น าไปใชงานกสามารถใชงานไดโดยสะดวก เนองจากการเรยกใชโอเวอรโหลดโอเปอเรเตอรสามารถ
เขาใจไดโดยงายและรไดเองโดยสญชาตญาณ
ตารางท 2-2 โอเวอรโหลดโอเปอเรเตอร
class CVector {
public:
int x,y;
CVector () {};
CVector (int, int);
CVector operator + (CVector);
};
CVector::CVector (int a, int b) {
x = a;
y = b;
}
โอเปอเรเตอรทสามารถโอเวอรโหลดได
/ % ^ | ~ ! < >
+= -= *= /= %= ^= &= |=
<< >> <<= >>= == != <= >=
&& || ++ -- , ->* new delete
ยนารและไบนาร สมาชกเทานน
+ - * & = [ ] ( ) ->
. ? : :: .* โอเวอรโหลดไมได
ตวอยางท 2-2 คลาส CVector และโอเวอรโหลดโอเปอเรเตอร +
ตวแปรสมาชก x,y
แบบ public
68
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
CVector CVector::operator + (CVector param) {
CVector temp;
temp.x = x + param.x;
temp.y = y + param.y;
return (temp);
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
CVector a (3,1);
CVector b (1,2);
CVector c, d;
c = a + b;
d = c.operator +(a);
cout << c.x << "," << c.y << endl;
cout << d.x << "," << d.y << endl;
}
จากตวอยางท 2-2 คลาส CVector ประกอบดวยตวแปรสมาชก x และ y เปนแบบ public ดงนนจง
สามารถเขาถงไดจากภายนอกโดยผานอนสแตนซของคลาส CVector สวน operator+ (CVector
param) เปนฟงกชนแบบโอเวอรโหลดโอเปอเรเตอร ซงเปนตวด าเนนการทางคณตศาสตร + ดงนน
เราสามารถน าวตถทสรางมาจากคลาส CVector มา + กนได เชน
c = a + b;
เปนการน า a มากระท าทางคณตศาสตร + กบ b จากนนถายคาไปเกบไวท c ซงเปนการเรยกใช
ฟงกชนโอเวอรโหลดโอเปอเรเตอร operator+ ดงนน c = a + b จงเทยบเทากบ
c = a.operator +(b);
น า x บวก param.x
น า y บวก param.y
สงคากลบเปนวตถของ CVector
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
69
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
ดงนน กลไกการท างานจงเปนการสง b เขาในฟงกชนโอเวอรโหลดโอเปอเรเตอร operator+ แลวน า
ตวแปรสมาชก x และ y ของ a และ b มาบวกกน จากนนสงผลลพธกลบแลวถายคาไวท c แตเรา
สามารถเรยกใชไดโดยลดรปแบบลงเหลอ c = a + b นนเอง
สงเกตวามฟงกชนคอนสตรคเตอรทไมไดมการก าหนดคาใดๆ ซงก าหนดไวในการประกาศคลาส
CVector () { };
ฟงกชนนจ าเปนตองสราง เนองจากเราไดสรางฟงกชนคอนสตรคเตอรทมสองพารามเตอร
CVector (int, int);
ดงนนฟงกชนคอนสตรคเตอรปรยายจงไมมการสรางใหโดยอตโนมต ไมเชนนน หากมการประกาศ
CVector vec จะไมสามารถประกาศได การสรางฟงกชนโอเวอรโหลดโอเปอเรเตอรเพอรองรบการ
ท างานทหลากหลายรปแบบ แสดงดงตวอยางท 2-3
CVector CVector::operator -(CVector param) {
CVector temp;
temp.x = x - param.x;
temp.y = y - param.y;
return (temp);
}
CVector CVector::operator ++() {
CVector temp;
temp.x = x + 1;
temp.y = y + 1;
return (temp);
}
ตวอยางท 2-3 การสรางโอเวอรโหลดโอเปอเรเตอรแบบตางๆ
สรางตวด าเนนการ – เรยกใช
โดย c = a - b;
สรางตวด าเนนการ ++ เรยกใช
โดย c = c++;
70
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
CVector CVector::operator *(int i) {
CVector temp;
temp.x = x * i;
temp.y = y * i;
return (temp);
}
CVector CVector::operator *(double d) {
CVector temp;
temp.x = int(x * d);
temp.y = int(y * d);
return (temp);
}
2.8 ค าสงวน this
ค าสงวน this ใชเปนตวแทนตวชของวตถ ซงใชในการเขาถงตวแปรและฟงกชนสมาชกของ
วตถทสรางมาจากคลาสทค าสงวน this วางอย นนกคอ this เปนตวชของวตถนนเอง
class CDummy {
public:
bool IsKindOf(CDummy& param);
};
bool CDummy::IsKindOf(CDummy& param) {
if (this == ¶m) return true;
else return false;
}
int _tmain(int argc, _TCHAR* argv[]) {
สรางตวด าเนนการ * เรยกใช
โดย c = a * 2;
สรางตวด าเนนการ * เรยกใช
โดย c = a * 2.9;
ตวอยางท 2-4 การใชตวชเพอตรวจสอบต าแหนงหนวยความจ าของวตถ
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
71
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
CDummy a;
CDummy* b = &a;
if ( b->IsKindOf(a) ) printf("Yes, &a is kind of b\n");
else printf("No, It is not me\n");
return 0;
}
□ ตวช this ใชเปนตวชของอนสแตนซของคลาส เรยกใชภายในฟงกชนสมาชกของคลาสนนๆ
□ ตวช this เปนตวเกบต าแหนงหนวยความจ าของอนสแตนซของคลาส ซงใชในการเขาถงสมาชก
ของมน
□ ตวช this ไมสามารถใชในการค านวณขนาดของวตถได
□ ตวช this ไมสามารถใชในการเขาถงสมาชกแบบสแตตกได
□ ตวช this ไมสามารถเปลยนแปลงคาต าแหนงได
จากตวอยางท 2-4 IsKindOf เปนฟงกชนทใชในการตรวจสอบต าแหนงหนวยความจ าของวตถทสง
เขามาในฟงกชนวาตรงกนกบต าแหนงหนวยความจ าของอนสแตนซของคลาส CDummy ซงตองใช
ค าสงวน this เทานนจงจะสามารถท าการเปรยบเทยบต าแหนงหนวยความจ าของวตถได
อกตวอยางกเปนการสงคากลบเปนต าแหนงหนวยความจ าของอนสแตนซของคลาสนนๆ เชน
CVector& CVector::operator = (const CVector& param) {
x = param.x;
y = param.y;
return *this;
}
*this เปนการคนคาขอมลทตวช this ชอย (ตวด าเนนการเขาถงขอมล (Value of Operator)) โดย
CVector& เปนการสงคากลบเปนต าแหนงหนวยความจ าของอนสแตนซของคลาส CVector
72
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
2.9 สมาชกแบบสแตตก
คลาสสามารถมตวแปรและฟงกชนสมาชกแบบสแตตกได ตวแปรสมาชกแบบสแตตกของ
คลาสเปนตวแปรของคลาส (Class Variable) เนองจากตวแปรแบบสแตตกจะถกสรางขนมาเพยงชด
เดยว ไมวาคลาสนนจะถกน าไปสรางเปนวตถมากเพยงใดกตาม ดงนนคาในตวแปรแบบสแตตกจง
เทากนหมด ไมวาจะเขาถงจากคลาส หรอจากวตถใดๆ ของคลาสกตาม ตวอยางการน าไปใชงานเชน
ใชเปนตวนบจ านวนของวตถทถกสรางขนมาจากคลาส หรอใชเปนตวแปรทใชรวมกน (S h a r e d
Variable) ระหวางวตถ เชน
class CDummy {
public:
static int n;
CDummy () { n++; };
~CDummy () { n--; };
};
int CDummy::n = 0;
int main () {
CDummy a;
CDummy b[5];
CDummy * c = new CDummy;
cout << a.n << endl;
delete c;
cout << CDummy::n << endl;
return 0;
}
เปนตวอยางการใชตวแปร n เปนตวนบจ านวนของวตถทสรางขนมาจากคลาส CDummy ซงไมวาจะ
เขาถงตวแปร n จากคลาสโดยตรงโดยใชค าสง
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
73
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
CDummy::n
หรอผานวตถโดยใชค าสง
a.n
ผลลพธทไดกจะเหมอนกน เนองจากตวแปร n จะมเพยงชดเดยว ดงนนไมวาจะเขาถงตวแปร n ผาน
วตถหรอคลาสจงไดคาเดยวกน
2.10 ฟงกชนและคลาสเพอน (Friend Class and Functions)
โดยทวไป ตวแปรและฟงกชนสมาชกแบบ private และ protected จะไมสามารถเขาถงไดจาก
ภายนอกคลาส นอกจากสมาชกในคลาสเดยวกนเทานน หากเราตองการประกาศฟงกชนหรอคลาส
ภายนอกใหสามารถเขาถงสมาชกของคลาสทเปนแบบ private และ protected ได เราสามารถประกาศ
โดยใชค าสงวน friend น าหนาฟงกชนหรอคลาส โดยประกาศไวในคลาสทจะใหฟงกชนหรอคลาส
อนเขาถง
class CMyClass {
int num;
public:
CMyClass(int x) {
num = x;
}
friend int isneg(CMyClass ob);
};
int isneg(CMyClass ob) {
return (ob.num < 0) ? 1 : 0;
}
ก าหนดใหฟงกชน isneg
เปนเพอนของ CMyClass
เปนตวแปรแบบ
private โดยปรยาย
74
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
int _tmain(int argc, _TCHAR* argv[]) {
CMyClass a(-1);
if(isneg(a))
printf("it is negative!\n");
else printf("it is positive!\n");
return 0;
}
ฟงกชน isneg ไมไดเปนสมาชกของคลาส CMyClass ดงนนโดยทวไปจงไมสามารถเขาถงตวแปร
num ได ซงเปนตวแปรแบบ private โดยปรยาย แตเนองจากมการก าหนดใหฟงกชน isneg เปนเพอน
ของคลาส CMyClass ดงนนฟงกชน isneg จงสามารถเขาถงตวแปร num ได
หากตองการใหคลาสใดๆ สามารถเขาถงสมาชกแบบ private หรอ protected ของอกคลาสก
สามารถท าไดโดยใชค าสงวนน าหนาการประกาศคลาส ดงน
class CTwoValues {
int a, b;
public:
CTwoValues(int _a, int _b) { a = _a; b = _b;}
friend class CMin;
};
class CMin {
public:
int findMin(CTwoValues x);
};
int CMin::findMin(CTwoValues x) {
return x.a < x.b ? x.a : x.b;
}
ก าหนดใหคลาส CMin เปน
เพอนของคลาส CTwoValues
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
75
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
int _tmain(int argc, _TCHAR* argv[]) {
CTwoValues two(7, 13);
CMin m;
printf("min is %d", m.findMin(two));
return 0;
}
ซงเปนการก าหนดใหคลาส CMin เปนเพอนของคลาส CTwoValues ดงนน CMin จงสามารถเขาถง
สมาชกของคลาส CTwoValues ได ถงแมจะเปนสมาชกแบบ private หรอ protected กตาม
ค าแนะน า
การก าหนดความเปนเพอน (friendship) ชวยใหการเขยนโปรแกรมสะดวกขน โดยท าใหฟงกชนหรอ
คลาสใดๆ สามารถเขาถงสมาชกแบบ private หรอ protected ได ท าใหเปนการละเมดกฏในการปกปอง
ขอมล ดงนนจงควรจะใชใหนอยทสด และใชเทาทจ าเปน
2.11 ความสมพนธระหวางคลาส (Class Relationship)
โดยทวไปความสมพนธระหวางคลาสม 3 แบบ ดงน
1. ความสมพนธแบบ "is-a" หรอ "is kind of" ซงเปนความสมพนธแบบการสบทอด โดยทคลาสหนง
เปนชนดหนงของอกคลาส เชน สเหลยมเปนชนดหนงของรปทรง มหาวทยาลยเปนชนดหนงของ
สถานศกษา และมหาวทยาลยเทคโนโลยมหานครกเปนชนดหนงของมหาวทยาลย เปนตน ดงนนการ
สบทอดจงเปนความสมพนธแบบ "is-a" / "is kind of"
: public
CShape
CRectangle
76
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
2. ความสมพนธแบบ "has-a" ซงเปนความสมพนธระหวางคลาส โดยทคลาสหนงอยภายในอกคลาส
หนง (Containment) ซงเปนการสรางคลาสหนง ใหเปนตวแปรสมาชกของอกคลาสหนง เชน รถยนต
มเครองยนต
3. ความสมพนธแบบ "uses-a" ซงเปนความสมพนธแบบฟงกชนสมาชกของคลาสหนง น า
อนสแตนซของอกคลาสมาเปนพารามเตอรในฟงกชน เชน รถยนตใชถนน ทหารใชอาวธ และการ
ประมวลผลภาพ (CImageProc) ใชภาพ (CImage) ในการเกบขอมล เปนตน
2.11.1 การสบทอดของคลาส (Inheritance)
การสบทอดเปนเทคนคทส าคญมากเปนอนดบตนๆ ของการเขยนโปรแกรมเชงวตถ ซงเปน
กลไกการถายทอดคณลกษณะจากคลาสหนงไปยงอกคลาสหนง การสบทอดในการเขยนโปรแกรม
เชงวตถมอยในหลายภาษา เชน จาวา C# และ C++ ซงเปนความสามารถทโดดเดนมาก เราสามารถ
สรางคลาสขนมาใหมโดยอาศยการสบทอดมาจากคลาสอน ท าใหไดตวแปรและฟงกชนสมาชกจาก
คลาสนนๆ โดยทยงไมตองมการสรางตวแปรและฟงกชนเพมเตมแตอยางใด
CCarCEngine
CImageProc
CImage
doHistogram(…)
CImage img;
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
77
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
□ คลาสทสรางขนมาใหมโดยไดจากการสบทอด เรยกวา ดไรฝคลาส (Derived Class) สบคลาส
(Sub Class) หรอไชลดคลาส (Child Class)
□ คลาสทถกสบทอด เรยกวา เบสคลาส (Base Class) ซเปอรคลาส (Super Class) หรอพาเรนท
คลาส (Parent Class)
ในต าราเลมนจะใชค าศพทสบคลาสและซเปอรคลาสเพอความสะดวกในการอธบาย ในภาษา C + +
การสบทอดจากซเปอรคลาสหลายๆ คลาส (Multiple Inheritance) สามารถท าได (ในภาษาจาวา ได
ตดความสามารถในการสบทอดจากหลายๆ คลาสทงไป แลวหลกเลยงการสบทอดจากหลายคลาส
โดยใชอนเตอรเฟส (In te r face) ) และการสบทอดตอจากสบคลาสกสามารถท าได ซงจะท าใหเกด
ล าดบชนของการสบทอด
การสบทอดท าใหเกดขอดในการเขยนโปรแกรมดงน
□ การน าค าสงทมอยแลวกลบมาใชใหม เมอมการสบทอดโดยการน าคลาสหนงไปสบทอดมาจากอก
คลาสหนง สมาชกจากซปเปอรคลาสจะถกถายทอดมายงสบคลาส (รปแบบการถายทอดจะได
กลาวถงตอไป) ท าใหสามารถน าฟงกชนทมอยแลวมาใชงานไดโดยไมตองเขยนใหม ซงเปนหนง
ในคณสมบตของการเขยนโปรแกรมเชงวตถ เรยกวาค าสงทน ากลบมาใชใหมได (R e u s a b l e
Code)
□ การสรางสบคลาสจากซเปอรคลาสโดยทมบางสวนเพมเตมขนมา เมอน าสบคลาสไปสบทอดมา
จากซเปอรคลาส สมาชกจากซเปอรคลาสจะถายทอดมายงสบคลาส ซงจะท าใหสบคลาสม
ความสามารถเทากบซเปอรคลาส นอกเหนอจากนน เรายงสามารถสรางตวแปรและฟงกชน
สมาชกเพมขนในสบคลาสได เพอเปนการเพมเตมความสามารถของสบคลาสใหมากขนกวาเดม
และเหมาะสมกบงานนนๆ เชน C E d i t เปนคลาสทท าหนาทในการรบอกขระ แลวแสดงบน
หนาจอ หากเราตองการเพมความสามารถใหกบ CEdit โดยใหตรวจสอบรหสแอสกทพมพตอง
เปนตวเลขเทานน (หมายเลขโทรศพท) หรอตองเปนตวอกษรเทานน (ชอ-นามสกล) หรอตองเปน
ตวเลขและจดทศนยมเทานน (หมายเลขไอพ) หากไมเปนไปตามทก าหนดกจะไมรบรหสแอสก
นน ดงนนเราสามารถสรางคลาสใหมชอ CPhoneEdit แลวน าไปสบทอดมาจาก CEdit สมาชก
78
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
□ ถายทอดคณลกษณะจากหลายคลาส เปนการสบทอดจากหลายคลาส โดยดงเอาคณลกษณะของ
แตละคลาสมาใชงาน เมอรวมเอาความสามารถจากหลายคลาสไดแลว กสามารถน าไปใหคลาส
อนสบทอดตอไดอก
□ จดการใหวตถมการสบทอดเปนล าดบชน การสบทอดเปนความสมพนธแบบคลาสใดคลาสหนง
เปนชนดหนงของอกคลาส (is a kind of) ซงการก าหนดล าดบความส าคญทถกตองเปนสวนหนง
ของการออกแบบการเขยนโปรแกรมเชงวตถทด เชน คลาสอาจารย (CLecturer) เปนชนดหนง
ของคลาสลกจาง (CEmployee) คลาสสเหลยม (CRectangle) เปนชนดหนงของคลาสรปทรง
(CShape) คลาสเมทรกซจตรส (Square Matrix) เปนชนดหนงของคลาสเมทรกซ (Matrix) คลาส
แมว (CCat) เปนชนดหนงของคลาสสตว (CAnimal) สตวเลยงลกดวยนม (CMammal) เปนชนด
หนงของสตว และคน (CHuman) กเปนชนดหนงของสตวเลยงลกดวยนม เปนตน ซงการสบทอด
จะท าใหเกดคณสมบตความเขากนไดของชนดขอมล (Compatible Type) ดงนนเราสามารถน า
วตถทเกดจากการสบทอดมาจากซเปอรคลาสเดยวกนมาท างานรวมกนได ท าใหเกดคณสมบต
การเปลยนรปไดหลากหลายแบบ (Polymorph ism) ซงเปนอกคณสมบตหนงทส าคญของการ
เขยนโปรแกรมเชงวตถ
ภาษา C++ สนบสนนการสบทอดจากคลาสเดยวหรอจากหลายคลาสกได ทงนขนอยกบประเภทของ
คลาสวาจ าเปนตองสบทอดมาจากหลายคลาสหรอไม ในสวนแรกของการสบทอดจะเปนการอธบาย
วธใชงานการสบทอดจากคลาสเดยว สวนการสบทอดจากหลายคลาสจะไดอธบายภายหลงทายบท
รปแบบการสรางสบคลาสเพอท าการสบทอดจากซเปอรคลาสเปนดงรปท 2-5
ของ CEdit จะถกถายทอดไปส CPhoneEdit ท าให CPhoneEdit และ CEdit มความสามารถเทา
เทยมกน จากนนกเพมความสามารถในการตรวจสอบรหสแอสกวาเปนตวเลข ตวอกษร หรอรหส
พเศษ โดยทตวเลขเทานนจะถกรบและแสดงผลใน CPhoneEdit ซงจะเหนไดวางานโดยสวนใหญ
จะเหมอนกนระหวาง CPhoneEdit และ CEdit มเพยงการตรวจสอบรหสแอสกเทานนทเพมขนมา
ใน CPhoneEdit ซงเปนการเขยนค าสงเพมเตมเพยงเลกนอย โดยท คณลกษณะสวนใหญจะถก
ถายทอดมาจาก CEdit ดงนนการถายทอดคณลกษณะจากซเปอรคลาสจงชวยลดงานในการเขยน
โปรแกรมลงไปไดมาก
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
79
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
จากรปท 2-5 เมอน าสบคลาสไปสบทอดจากซเปอรคลาส โดยใช : p u b l i c ซงท าให
คณลกษณะ (ตวแปรและฟงกชนสมาชกทท างานเฉพาะใหกบซเปอรคลาส ทเปนแบบ public และ
pro tec ted) ทมอยในซเปอรคลาส ถกถายทอดลงมายงสบคลาส ท าใหสบคลาสมความสามารถเทา
เทยมกนกบซเปอรคลาส หรอกลาวไดอกในหนงวา สบคลาสท าตวเสมอนซเปอรคลาส
นอกเหนอจากนนเรายงสามารถเพมเตมคณลกษณะเฉพาะของสบคลาส เพอใหท างานตาม
วตถประสงคของสบคลาสนนๆ อนเปนการขยายความสามารถของซเปอรคลาสใหมากขน โดยไม
ตองสรางขนมาใหมทงหมด
2.11.2 อะไรบางทไมไดถกถายทอดลงสบคลาส
โดยปกตแลว สมาชกของซเปอรคลาสจะถกถายทอดลงสบคลาส ยกเวน
□ ฟงกชนคอนสตรคเตอรและฟงกชนดสตรคเตอรของซเปอรคลาส
□ โอเปอเรเตอรสมาชก operator = ( )
□ เพอนของซเปอรคลาส
□ ตวแปรและฟงกชนสมาชกแบบ private
ถงแมวาฟงกชนคอนสตรคเตอรและฟงกชนดสตรคเตอรจะไมถกถายทอดไปยงสบคลาส แตมนจะ
รปท 2-5 การสบทอดจาก
ซเปอรคลาสและการ
ถายทอดคณลกษณะ
จากซเปอรคลาส
ไปยงสบคลาส
class : public {
...
...
};
: public
80
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ในการก าหนดความสมพนธระหวางคลาส ใหพจารณาทความถกตองและความเหมาะสมใน
การน าไปใชงาน หากเราตองการสรางคลาสในการเกบทอยของแฟมขอมล (Path Name) ซงทอยของ
แฟมขอมลกเปนสตรง ดงนนจงตองมสองคลาสคอ CPathName และ CString ซงสามารถก าหนด
ความสมพนธไดสองแบบคอ “is-a” และ “has-a” แสดงดงรปท 2-6
โดยท
□ CPathName เปนคลาสทท าหนาทในการจดการทอยของแฟมขอมล เชน การแยกชอไดรฟ การ
แยกเฉพาะไดเรกตอร หรอการก าหนดใหลงทายดวย \ เปนตน
□ CString เปนคลาสทท าหนาทในการจดการสตรง เชน การท าส าเนาสตรง การตอทายสตรง และ
การเปรยบเทยบสตรง เปนตน
รปท 2-6 ความสมพนธ
ระหวางคลาส
(a) ความสมพนธ
แบบ “is-a” และ
(b) ความสมพนธ
แบบ “has-a”
: public
CString
CPathName
CPathNameprivate : CString
reverseString(…)
reverseString(…)
CPathName path;
reverseString(…)
path.reverseString(…)
reverseString(…)
CPathName path;
reverseString(…)
ก ข
ถกเรยกใชโดยอตโนมตหากอนสแตนซของคลาสถกสรางขนมา ซงการสบทอดมประโยชนในหลาย
ดาน โดยเฉพาะการลดค าสงและความซ าซอนในการเขยนโปรแกรม
□ การถายทอดคณลกษณะจากซเปอรคลาสมายงสบคลาส เปนความสามารถในการเขยนโปรแกรม
เชงวตถ ดานการน าค าสงกลบมาใชใหม (Reusable Code)
□ คณลกษณะเพมเตมของสบคลาสทสรางขนมา เปนการขยายความสามารถใหเปนไปตามงาน
เฉพาะของสบคลาส เชนการเพมความสามารถในการตรวจสอบรหสแอสกของ CPhoneEdit ซง
เปนความสามารถในการเขยนโปรแกรมเชงวตถ ดานการขยายคณลกษณะ (Extensible Feature)
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
81
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
รปแบบทหนง เราอาจก าหนดใหความสมพนธระหวางสองคลาสเปนแบบ "is-a" โดยให CPathName
คอ CString (CPathName is a CString) ซงเปนการก าหนดความสมพนธผดรปแบบ เนองจาก
CPathName ท าหนาทในการจดการสตรง เพอท าใหสามารถเกบทอยของแฟมขอมลใหถกตอง ซงท
อยของแฟมขอมลถกเกบอยในรปแบบของสตรง ดงนน ถงแมวาทอยของแฟมขอมลจะมรปแบบ
สตรง แตทอยของแฟมขอมลไมใชเปนชนดหนงของสตรง ซงหากเราสบทอด C P a t h N a m e จาก
CString คณลกษณะของ CString จะถกถายทอดมายง CPathName เชน การท าสตรงกลบดาน (String
Reversal) ดงนนเมอน า CPathName ไปใชงานโดยสรางเปนวตถ เราสามารถเรยกใชฟงกชนทท าให
สตรงกลบดานได (รปท 2-6 (ก)) ซงจะท าใหผลลพธจากสตรง "C:\WINDOWS" กลายเปน
"SWODNIW\:C" จะเหนไดวาเปนการท าใหรปแบบของทอยของแฟมขอมลผดรปแบบไป ดงนนจง
ไมเหมาะสม
รปแบบทสอง เปนการก าหนดความสมพนธแบบ “has-a” โดยใหสรางวตถจากคลาส CString เปนตว
แปรสมาชกแบบ private ภายในคลาส CPathName ซงท าใหภายนอกไมสามารถเขาถงอนสแตนซท
สรางจากคลาส CString ได มเฉพาะสมาชกในคลาส CPathName เทานนทสามารถเขาถงอนสแตนซ
ทสรางจาก CString ได ท าใหเราสามารถก าหนดวธการจดการสตรงในคลาส CPathName ไดถกตอง
เชน เมอน า CPathName ไปสรางเปนอนสแตนซ เราไมสามารถเขาถงฟงกชน reverseString ได
ดงนนสตรงทอยภายในทอยของแฟมขอมลไมสามารถกลบดานได (รปท 2-6 (ข)) ดงนนจงมนใจได
วาภายนอกไมสามารถเปลยนแปลงสตรงได เพยงแคน าไปใชงานได แตไมสามารถเปลยนแปลงได
ท าใหเกดความสมพนธทอยของแฟมขอมลเกบอยในรปแบบสตรง ซงในกรณเชนน การก าหนด
ความสมพนธแบบ “has-a” เหมาะสมกวา
ตวอยางการสรางคลาสพนกงาน
สมมตวาเราตองการสรางคลาสทเกยวกบพนกงานในบรษท ซงมคลาสทตองสรางดงตอไปน
□ พนกงาน (Employee)
□ ผจดการ (Manager)
□ ผใหค าแนะน า (Supervisor)
82
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
มขอมลทตองจดเกบดงน
□ ชอ (Name)
□ อตราการจายเงน (Pay Rate)
และมฟงกชนดงตอไปน
□ ฟงกชนในการก าหนดคาเรมตนใหพนกงาน (ฟงกชนคอนสตรคเตอร)
□ ฟงกชนในการดงชอพนกงาน (getName)
□ ฟงกชนในการดงอตราการจายเงน (getPayRate)
□ ฟงกชนในการค านวณเงนทพนกงานไดรบ (pay)
ดงนนเราสามารถสรางคลาสพนกงานไดดงตวอยางท 2-5
class CEmployee {
public:
CEmployee(string theName, float thePayRate);
string getName() const;
float getPayRate() const;
float pay(float hoursWorked) const;
protected:
string name;
float payRate;
};
CEmployee::CEmployee(string theName, float thePayRate) {
name = theName;
payRate = thePayRate;
}
ตวอยางท 2-5 คลาสพนกงาน
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
83
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
string CEmployee::getName() const {
return name;
}
float CEmployee::getPayRate() const {
return payRate;
}
float CEmployee::pay(float hoursWorked) const {
return hoursWorked * payRate;
}
จากตวอยางท 2-5 ฟงกชน pay ท าหนาทในการค านวณรายไดทไดรบจากจ านวนชวโมงคณดวยอตรา
การจายเงน ซงเปนรายไดคดตามชวโมงทท างาน ฟงกชนคอนสตรคเตอรท าหนาทในการก าหนดคา
เรมตนใหกบชอพนกงานและอตราการจายเงน สงเกตวาตวแปร name และ payRate เปนการก าหนด
รปแบบการเขาถงแบบ protected ซงท าใหสมาชกในคลาสและสบคลาสเทานน จงจะสามารถเขาถง
ตวแปรเหลานได ดงนนเราสามารถน าคลาส CEmployee มาใชงานไดดงน
ตอมาเราตองการสรางคลาสผจดการ ซงโดยทวไป กตองมการเกบคาตวแปรตางๆ และม
ฟงกชนเหมอนพนกงานทวไป แตอาจมขอแตกตางในบางอยาง เชน ผจดการไดรบคาตอบแทนเปน
เงนเดอน โดยไมเอาชวโมงท างานมาคด ดงนนจงมตวแปรสมาชกเพมดงน
□ ตวแปรบงชวาจายเปนเงนเดอน (salaried)
และมฟงกชนเพมเตมดงน
CEmployee empl("John Burke", 25.0);
cout << "For Employee:" << endl;
cout << "Name: " << empl.getName().c_str() << endl;
cout << "Pay: " << empl.pay(40.0) << endl;
ดงชอมาแสดง
แสดงรายได
84
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
□ ฟงกชนในการดงคาตวบงชเงนเดอน (getSalaried)
ดงนนคลาสผจดการสามารถเขยนไดดงตวอยางท 2-6
class Manager {
public:
Manager(string theName, float thePayRate, bool isSalaried);
string getName() const;
float getPayRate() const;
bool getSalaried() const;
float pay(float hoursWorked) const;
protected:
string name;
float payRate;
bool salaried;
};
Manager::Manager(string theName, float thePayRate, bool isSalaried) {
name = theName;
payRate = thePayRate;
salaried = isSalaried;
}
string Manager::getName() const {
return name;
}
float Manager::getPayRate() const {
return payRate;
}
ตวอยางท 2-6 คลาสผจดการ
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
85
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
bool Manager::getSalaried() const {
return salaried;
}
float Manager::pay(float hoursWorked) const {
if (salaried)
return payRate;
else
return hoursWorked * payRate;
}
จากตวอยางท 2-6 มฟงกชนทเพมขนมาคอ getSalaried เพอสงคาตวบงชเงนเดอนกลบ และฟงกชน
pay มการแกไขใหตรวจสอบตวแปร salaried หากเปนจรงจะคดรายไดเปนเงนเดอน นอกนนฟงกชน
มการท างานเหมอนกบคลาสพนกงาน
ซงจะเหนไดวา เปนการเขยนโปรแกรมทซ ากบตวแปรและฟงกชนทมอยแลวในคลาส
พนกงาน ซงเปนงานทซ าซอนและเกนความจ าเปน ดงนนเราสามารถใชเทคนคการเขยนโปรแกรม
เชงวตถ เพอชวยลดงานทซ าซอนลงได โดยน าคลาสผจดการไปสบทอดจากคลาสพนกงาน เนองจาก
ผจดการกเปนชนดหนงของพนกงาน (Manager is kind of an Employee) เมอสบทอดแลว เราจะได
คณลกษณะจากพนกงาน จากนน กเพยงแตเพมงานทตองการลงไปในคลาสผจดการ ทมความ
แตกตางจากคลาสพนกงาน ดงนนคลาสผจดการสามารถเขยนใหมไดดงน
class CManager : public CEmployee {
public:
CManager(string theName, float thePayRate, bool isSalaried);
bool getSalaried() const;
float pay(float hoursWorked) const;
protected: bool salaried;
};
ตวอยางท 2-7 คลาสผจดการทสบทอดมาจากคลาสพนกงาน
CManager สบทอด
จาก CEmployee
86
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
CManager::CManager(string theName, float thePayRate, bool isSalaried)
: CEmployee(theName, thePayRate) {
salaried = isSalaried;
}
bool CManager::getSalaried() const {
return salaried;
}
float CManager::pay(float hoursWorked) const {
if (salaried)
return payRate;
else
return CEmployee::pay(hoursWorked);
}
จากตวอยางท 2-7 เมอน าคลาสผจดการไปสบทอดมาจากคลาสพนกงาน ท าใหคลาสผจดการไดรบ
การถายทอดคณลกษณะจากคลาสพนกงาน ท าใหไมจ าเปนตองสรางตวแปรและฟงกชนสมาชกท
ซ าซอนกน เมอสบทอดแลว เพยงแตสรางตวแปรและฟงกชนสมาชกทตองการเพมเตมจากคลาส
พนกงาน ท าใหการเขยนโปรแกรมลดลงไปมาก การเขยนโปรแกรมในรปแบบนเปนคณสมบตการ
น าค าสงกลบมาใชใหม (Reusable Code) ซงเปนคณสมบตทส าคญในการเขยนโปรแกรมเชงวตถ
ฟงกชนทมความแตกตางคอฟงกชน pay ในคลาสผจดการ โดยท าการตรวจสอบวาจายเปนเงนเดอน
หรอไม หากใชให
return payRate;
ซงเปนการจายตามอตราเงนเดอน หากไมใช (salaried เปน FALSE) ให
return CEmployee::pay(hoursWorked);
ซงเปนการเรยกใชฟงกชน pay ในคลาส CEmployee โดยกระท าผาน ::
เรยกใชฟงกชนคอนสตรค
เตอรของซเปอรคลาส
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
87
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
เมอสรางคลาส CManager เสรจแลว สามารถน ามาเรยกใชงานไดดงน
CManager mgr("Jan Kovacs", 1200.0, true);
cout << "For Manager:" << endl;
cout << "Name: " << mgr.getName().c_str() << endl;
cout << "Salaried: " << mgr.getSalaried() << endl;
cout << "Pay: " << mgr.pay(40.0) << endl;
โครงสรางของคลาส CManager ทสบทอดมาจากคลาส CEmployee แสดงดงรปท 2-7
รปท 2-7 โครงสราง
การสบทอดระหวาง
คลาส CManager
และ CEmployee
ขอควรจ า
คลาสทสบทอดมาจากคลาสอนเรยกวา สบคลาสหรอดไรดคลาส
คลาสทถกสบทอดเรยกวา เบสคลาสหรอซเปอรคลาส
การเขาถงและการถายทอดสมาชกในคลาสมสามระดบ
□ สมาชกแบบ public ของซเปอรคลาสจะกลายเปนสมาชกแบบ public ของสบคลาส
□ สมาชกแบบ private ของซเปอรคลาสจะไมสามารถเขาถงไดจากสมาชกของสบคลาส
□ สมาชกแบบ protected ของซเปอรคลาสจะกลายเปนสมาชกแบบ private ของสบคลาสเมอมการ
เขาถงจากภายนอก
: public
CEmployee
CManager
getName()getPayRate()pay()
namepayRate
getName()getPayRate()pay()
namepayRate
getSalaried()pay()salaried
88
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
2.12 การสบทอดจากหลายทาง
เราสามารถสบทอดคณลกษณะจากคลาสเดยวหรอหลายคลาสกได ซงคณสมบตนมอยใน
ภาษา C++ แตถกตดทงไปในภาษาจาวา การสบทอดท าใหคณลกษณะจากซเปอรคลาสถกถายทอดลง
ไปยงสบคลาส ดงนนสบคลาสจงท าตวเสมอนเปนซเปอรคลาส หากน าคลาสไปสบทอดมาจากหลาย
คลาส สบคลาสกท าตวเสมอนคลาสเหลานน เชน หากเราตองการสรางงานเกยวกบรปทรงทาง
เรขาคณต คลาสทตองสรางอาจมดงน
□ คลาสโพลกอน (CPolygon) ท าหนาเปนคลาสทวไปของรปทรง
□ คลาสผลลพธ (COutput) ท าหนาทในการแสดงผลออกหนาจอ
□ คลาสสเหลยม (CRectangle) ท าหนาทเปนคลาสเพอท างานตามความสามารถของคลาสสเหลยม
□ คลาสสามเหลยม (C T r i a n g l e ) ท าหนาทเปนคลาสเพอท างานตามความสามารถของคลาส
สามเหลยม
ดงนนเราสามารถก าหนดความสมพนธของทงสคลาสไดดงรปท 2-8 โดยท C R e c t a n g l e
ตองการความสามารถจากรปทรงและการแสดงผล ซงตองสบทอดจาก CPolygon และ COutput จง
จะท าใหคณลกษณะของ CPolygon และ COutput ถกถายทอดลงไปยง CRectangle ในท านอง
เดยวกนการสบทอดของ CTriangle กเปนไปในลกษณะเดยวกน ตวอยางการสบทอดแบบหลายทาง
แสดงดงตวอยางท 2-8
รปท 2-8 ความสมพนธ
ของการสบทอด
แบบหลายทาง
CPolygon COutput
CRectangle CTriangle
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
89
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
ตวอยางท 2-8 การสบทอดแบบหลายทาง
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b;}
};
class COutput {
public:
void output (int i);
};
void COutput::output (int i) {
cout << i << endl;
}
class CRectangle: public CPolygon, public COutput {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon, public COutput {
public:
int area ()
{ return (width * height / 2); }
};
จากตวอยางท 2-8 เมอน า CRectangle ไปสบทอดมาจาก CPolygon และ COutput แลว จะได
90
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ความสามารถจากทงสองคลาส ท าใหเราสามารถเรยกใชฟงกชน set_values ซงเปนฟงกชนสมาชก
ของ CPolygon และฟงกชน output ซงเปนสมาชกของ COutput โดยการเรยกใชงานสามารถท า
ไดดงน
2.13 การท าโพลมอฟซม
คณลกษณะทส าคญอกอยางหนงของการสบทอดคอ ตวชของสบคลาสเปนชนดขอมลทเขา
กนได (Compatible Type) กบตวชของซเปอรคลาส ดงนนเราจงสามารถน าอนสแตนซของซเปอร
คลาสชไปยงอนสแตนซของสบคลาสได ซงเปนหนงในขอดทส าคญของการเขยนโปรแกรมเชงวตถ
หากน าซเปอรคลาสไปรบพารามเตอรจากสบคลาส แลวซเปอรคลาสสนบสนนตวประสานแบบ
พบบลคทงหมด ดงนนเราสามารถเขยนชดค าสงใหสามารถเรยกใชงานฟงกชนสมาชกในสบคลาส
ไดทกคลาสทเขากนไดกบซเปอรคลาส โดยใชชดค าสงเพยงชดเดยว
แนวความคดในการสรางและใชงานวตถ โดยทวตถเหลานนสามารถท างานรวมกนได หาก
คลาสเหลานนท าการสบทอดมาจากซเปอรคลาสตวเดยวกน ซงเปนการสรางตวเชอมตอทเขากนได
(Plug Compatible) เราสามารถมองเหนระบบทสรางมาตรฐานเดยวกนเพอใหสงของหรอวธการของ
แตละโรงงานทสรางออกมาสามารถท างานไดเหมอนกน เชน หลอดไฟเกลยว ไมวาจะเปนยหอใด ก
จะมขนาดเดยวกน แตกตางกนเพยงเรองประสทธภาพในการใชพลงงาน ตวเชอมตอทเขากนไดคอ
เกลยว หรอในการขบรถยนต หากเราสามารถขบรถยหอหนงได เรากสามารถทจะขบรถอกยหอหนง
ไดเชนกน โดยทไมตองมการเรยนรใหมทงหมด ถงแมวาเครองยนตของแตละยหอจะไมเหมอนกน
แตวธการขบรถกยงเหมอนเดม
เทคนคการสรางตวเชอมตอของวตถทเขากนได ถกนยามในภาษา C++ วาโพลมอฟค
(Polymorphic) ซงเปนวธการทชวยใหการเขยนโปรแกรมเชงวตถ สามารถลดค าสงลงไปไดมาก
CRectangle rect;
CTriangle tri;
rect.set_values (4,5);
tri.set_values (4,5);
rect.output (rect.area());
tri.output (tri.area());
เรยกใช set_values ของ CPolygon
เรยกใช output ของ COutput
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
91
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
แนวคดการเขยนโปรแกรมดวยวธการโพลมอฟซม คลายกบการท าตวชฟงกชน ผเขยนแนะน าให
นกพฒนาอานรายละเอยดเรองตวชฟงกชนในบทท 1 กอนทจะอานในหวขอน
หากเราสรางคลาส C P o l y g o n เพอใหเปนคลาสทวไปของรปทรง จากนนสรางคลาส
CRectangle และ CTriangle โดยน าไปสบทอดจากคลาส CPolygon ดงนนสบคลาส CRectangle และ
CTriangle จงเปนคลาสชนดเดยวกนทเขากนได เนองจากสบทอดมาจากซเปอรคลาสเดยวกน ในการ
น าไปใชงานเราสามารถน าตวชของคลาส CPolygon ชไปยงอนสแตนซของสบคลาส CRectangle
และ CTriangle ได จากนนกสามารถเรยกใชฟงกชนทมอยในซเปอรคลาสได ดงตวอยางท 2-9
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};
class CRectangle: public CPolygon {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area ()
{ return (width * height / 2); }
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
CRectangle rect;
ตวอยางท 2-9 การใชตวชของซเปอรคลาสชไปยงอนสแตนซของสบคลาส
92
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
CTriangle tri;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &tri;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << rect.area() << endl;
cout << tri.area() << endl;
}
จากตวอยางท 2-9 เราสรางตวชของคลาส CPolygon สองตวคอ ppoly1 และ ppoly2 ดงนนเมอใหช
ไปยงต าแหนงหนวยความจ าของอนสแตนซของ CRectangle และ CTriangle
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &tri;
จงสามารถท าได เนองจาก CRectangle และ CTriangle สบทอดมาจาก CPolygon ดงนนจงเปนการ
ก าหนดทถกตอง
ขอจ ากดในการเรยกใชฟงกชนจาก ppoly1 และ ppoly2 คอทงสองอนสแตนซสรางมาจาก
คลาส CPolygon ดงนนเราสามารถเรยกใชฟงกชนท CRectangle และ CTriangle สบทอดมาจาก
CPolygon เทานน ซงกคอฟงกชน set_values นนเอง ดงนนเราสามารถเรยกใชฟงกชนไดดงน
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ฟงกชน area ไมมใน CPolygon ดงนนเราจงไมสามารถเรยกใชฟงกชน area โดยตรงได หากจะ
เรยกใชตองเรยกผาน rect.area หรอ tri.area อยางไรกตามหากตองการเรยกใชฟงกชน area โดยใชตว
ชของคลาส CPolygon เราจะตองสรางฟงกชน area ใน CPolygon ดวย แตเนองจากฟงกชน area ม
ความแตกตางกนในแตละคลาส เนองจากเปนการค านวณหาพนท ดงนนการเขยนค าสงในการ
ค านวณลงในฟงกชน area ของคลาส CPolygon จงไมเหมาะสม
ให ppoly1 ชไปยง &rect
เรยกใช set_values
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
93
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
ความสามารถของโปรแกรม หรอฟงกชนทสามารถท างานไดกบชนดของวตถทหลากหลาย
เรยกวาโพลมอฟซม นนกคอเราสามารถเขยนฟงกชน เพอท างานกบชนดของวตถทหลากหลายได
โดยทมชดค าสงเพยงชดเดยวในฟงกชน (โดยปกตหากมชนดของวตถหลายประเภท เราอาจสรางเปน
ฟงกชนโอเวอรโหลด เพอใหรบพารามเตอรในแบบตางๆ ได โดยทฟงกชนนนมชอเดยวกน แตม
พารามเตอรตางกน แตในทน เราจะเขยนเพยงหนงฟงกชนแตสามารถรบชนดของวตถไดหลาย
ประเภท โดยอยบนสมมตฐานทวา วตถนนมชนดทเขากนได)
เทคนคในการสรางคลาสเพอใหวตถมความเขากนได มดงน
□ ใชซเปอรคลาสเปนตวชหรอตวแปรอางอง เชน หาก CRectangle และ CTriangle เปนสบคลาส
โดยสบทอดมาจาก CPolygon ดงนนเราสามารถน า CPolygon มาสรางเปนตวชได โดยทวตถของ
CRectangle และ CTriangle จะถกสงเขามาในฟงกชน ซงตวชของ CPolygon สามารถรบได
เนองจากเปนชนดของวตถทมความเขากน
□ ใชตวประสานพบบลคทมรปแบบทวไป เชน ฟงกชน Draw ท าหนาทในการวาดรป ซงการวาด
รปของแตละรปทรงจะแตกตางกนไป แตท าหนาทเดยวกนคอการวาดรป ดงนนเราสามารถ
เรยกใชฟงกชน Draw เพอวาดเปนรปทรงของแตละวตถ โดยทฟงกชน Draw มความหมาย
เดยวกน
2.14 ฟงกชนเวอรชวล (Virtual Function)
ฟงกชนเวอรชวลคอฟงกชนสมาชกของคลาส (ซเปอรคลาส) ซงคาดหวงวาจะถกนยามขนมา
ใหมในสบคลาส เมอเราอางถงวตถของสบคลาสโดยใชตวชหรอตวอางองของซเปอรคลาส เรา
สามารถเรยกใชฟงกชนเวอรชวลได โดยทฟงกชนนนเปนของสบคลาส หากสรางฟงกชนเปนแบบ
เวอรชวล จะท าใหมนใจไดวาเราเรยกใชฟงกชนไดถกตอง ไมวาฟงกชนนนจะเปนของสบคลาสหรอ
ซเปอรคลาสกตาม ฟงกชนเวอรชวลมรปแบบดงน
virtual ชนดขอมลสงกลบ ชอฟงกชน(พารามเตอร);
ฟงกชนเวอรชวลมรปแบบการสรางเหมอนฟงกชนในแบบปกต แตมค าสงวน virtual น าหนาฟงกชน
94
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
ซงเปนการก าหนดใหสบคลาสทมาสบทอด จะตองท าการสรางฟงกชนเวอรชวลขนในสบคลาสดวย
เพราะฉะนนฟงกชนเวอรชวลจะถกใชเปนตวแทนของกลมของฟงกชน ทมรปแบบเดยวกน (ชนด
ขอมลสงกลบ ชอฟงกชน พารามเตอรเหมอนกน) ในการสบทอดเปนล าดบชนของคลาส เชน
ฟงกชน
void Draw(void);
ของคลาส CPolygon CRectangle และ CTriangle เปนตน การเรยกใชฟงกชนเวอรชวล จะท าในขณะ
รน (Run Time) ผานตวชหรอตวอางองของซเปอรคลาส ซงฟงกชนใดจะถกเรยกใชภายในกลมจะ
ขนอยกบชนดของวตถนน ดงแสดงในรปท 2-9
จากตวอยางท 2-9 เราไมสามารถเรยกใชฟงกชน area จากตวช ppoly1 หรอ ppoly2 ได เนองจาก
CPolygon ไมมฟงกชน area นยามไว หากตองการใหเรยกใชฟงกชน area จาก ppoly1 หรอ ppoly2
ได จะตองสรางฟงกชน area ไวใน CPolygon อยางไรกตามฟงกชน area ท าหนาทในการสงคาพนท
ของรปทรงกลบ ซง CPolygon ยงไมไดระบวาจะเปนรปทรงอะไร ดงนนฟงกชน area ควรจะสราง
เปนฟงกชนเวอรชวล เพอใหค าสงของฟงกชน area ถกเขยนอยในสบคลาสจงจะถกตอง ซงเขยนได
ใหมในตวอยางท 2-10
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
รปท 2-9 ฟงกชน
เวอรชวลทถกเรยกใช
ในขณะรน
ตวอยางท 2-10 ฟงกชนเวอรชวลในคลาส CPolygon
.vir_func()
->vir_func()
::vir_func()
1::vir_func()
2::vir_func()
3::vir_func()
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
95
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
{ width=a; height=b; }
virtual int area ()
{ return (0); }
};
class CRectangle: public CPolygon {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area () { return (width * height / 2); }
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
CRectangle rect;
CTriangle trgl;
CPolygon poly;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
CPolygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
cout << ppoly3->area() << endl;
}
ppoly1 ชไปทตวอางองของ rect
เรยกใช set_values ของ CPolygon
เรยกใช area ของ CRectangle
96
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
จากตวอยางท 2-10 คลาส CPolygon CRectangle และ CTriangle มสมาชกเหมอนกนคอ width
height set_values และ area ซงฟงกชนสมาชก area ถกนยามใหเปนฟงกชนแบบเวอรชวล ท าใหตอง
ถกนยามขนมาใหมอกครงในสบคลาส การเรยกใช
ppoly1->set_values (4,5);
เปนฟงกชนสมาชกของ CPolygon แตการเรยกใช
ppoly1->area();
จะเปนการเรยกใชฟงกชนสมาชกของคลาส CRectangle เนองจากตวช ppoly1 ไดชไปยงตวอางอง
ของ rect นนเอง
2.15 ซเปอรคลาสแบบนามธรรม (Abstract Base Class)
เราสามารถสรางฟงกชนเวอรชวลโดยทไมมการสรางค าสงใดๆ เลย โดยใชค าสงวน virtual
น าหนาฟงกชน และลงทายดวย = 0 ดงน
virtual ชนดขอมลสงกลบ ชอฟงกชน(พารามเตอร) = 0;
เชนฟงกชน area เปนฟงกชนทแสดงพนทของรปทรงใดๆ ซงไมควรมการเขยนค าสงในการท างาน
ในฟงกชน area ทอยในคลาส CPolygon เนองจากยงเปนงานทเปนนามธรรม สวนงานทเปนรปธรรม
คอค าสงทจะตองถกเขยนในฟงกชน area ของคลาสทสบทอดจาก CPolygon เพราะฉะนนคลาส
CPolygon สามารถเขยนใหมไดดงน
class CPolygon {
protected:
int width, height;
public:
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
97
C+
+ C
++
C
++
C+
+
Part I: Basic Idea & Concept
2
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area () = 0;
};
ฟงกชนเวอรชวล area ถกก าหนดใหมคา = 0 (NULL) โดยทไมมสวนของค าสงในการท างาน
ซงเรยกฟงกชนแบบนวา ฟงกชนเวอรชวลบรสทธ (Pure Virtual Function) ความแตกตางระหวาง
คลาสทวไปกบคลาสแบบนามธรรมคอ เราไมสามารถสรางอนสแตนซของคลาสได เชน
CPolygon poly; CPolygon เปนคลาสแบบนามธรรมแลว น าไปสรางเปนวตถไมได
ไมสามารถนยามได อยางไรกตามเราสามารถสรางตวชของคลาสแบบนามธรรมได ดงน
CPolygon * ppoly1;
CPolygon * ppoly2;
ฟงกชนเวอรชวลบรสทธ
98
บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++
C+
+ C+
+
C+
+
C+
+
แบบฝกหดทายบท
1. จงเปรยบเทยบขอแตกตางระหวางคลาสและสตรคเจอร วามขอดขอเสยตางกนอยางไร
2. จงอธบายประโยชนในการใชงานฟงกชนคอนสตรคเตอรและฟงกชนดสตรคเตอร
3. หากตองการเขยนโปรแกรมเพอวาดภาพเปนบลอกไดอะแกรม จงออกแบบคลาสทมในระบบ
4. หากตองการเขยนโปรแกรมใหวาดรปทรงไดทกรปแบบ แตใหมค าสงในการเรยกใชฟงกชน
OnPaint ของวตถเพยงชดเดยว เราตองใชความสามารถใดของการเขยนโปรแกรมเชงวตถ
5. หากตองการใชวตถสองตวสามารถกระท าตวด าเนนการทางคณตศาสตรได เชน + - จงเขยนคลาส
CMyDate เพอใหสามารถ + - กนได
6. จงอธบายขอดในการสบทอด ในการเขยนโปรแกรมเชงวตถ
7. หากตองการเขาถงสมาชกของคลาสแบบ private และ protected จากภายนอก เราสามารถใชกลไก
การท างานแบบใด จงอธบาย
8. สมาชกของซปเปอรคลาสใดบางทไมไดถกถายทอดไปยงสบคลาส จงอธบาย
9. จงอธบายความหมายของชนดของคลาสทเขากนได
10. จงอธบายความแตกตางระหวางสมาชกแบบ public protected และ private