116
มหาวิทยาลัยเทคโนโลยีมหานคร การเขียนโปรแกรม สาหรับวินโดวส์ด้วย Visual C++ C++ Never Die ดร.สนั ่น ศรีสุข ภาควิชาวิศวกรรมคอมพิวเตอร์ A Language for High Performance Computing

VC-BookExample

Embed Size (px)

Citation preview

Page 1: VC-BookExample

มหาวทยาลยเทคโนโลยมหานคร

การเขยนโปรแกรม

ส าหรบวนโดวสดวย

Visual C++

C++ Never Die

ดร.สนน ศรสข

ภาควชาวศวกรรมคอมพวเตอร

A Language for High Performance Computing

Page 2: VC-BookExample

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

Page 3: VC-BookExample

การเขยนโปรแกรมบน

วนโดวสดวย Visual C++

ดร.สนน ศรสข

โครงการต าราวชาการ

ภาควชาวศวกรรมคอมพวเตอร

มหาวทยาลยเทคโนโลยมหานคร

Page 4: VC-BookExample

ค าอธบายหนาปก

หนาปกเปนรปสงโตสองตวหนหนาเขาหากน ทมองบางสงอยางมจดหมาย ซงมความหมาย

เชงสญลกษณดงน

ท าไมตองเปนสงโต ?

สงโตถอไดวาเปนราชาของสตวปา ซงอยในล าดบชนบนสดของสตวนกลา แขงแรง ดราย

และไมมศตรตามธรรมชาต หากเปรยบเทยบการเขยนโปรแกรมบนระบบคอมพวเตอรแลวนน ไมวา

จะเปนระบบปฏบตการวนโดวส ยนกส และลนกซ ภาษา 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

Page 5: VC-BookExample

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

Page 6: VC-BookExample

IV

การเขยนโปรแกรมบนวนโดวสดวย Visual C++

C+

+ C+

+

C+

+

C+

+

สญลกษณทใชในต าราเลมน

ในต าเราเลมน มการใชสญลกษณเพอเปนหมายเหตเพมเตม โดยมความหมายดงน

เปนค าแนะน า หรอค าอธบายเพมเตม

เปนสวนทควรระวง เมอเขยนโปรแกรมแลว อาจท าโปรแกรมหยดท างานได

เปนสวนทมรายละเอยดนาสนใจ อาจเปนหวใจหลกของเรองนน ซงควรมการ

จดบนทกไว

เปนขอควรคด หรอสรปแนวคดของเนอหานนๆ

เปนขอควรระวงทตองระมดระวงในการเขยนโปรแกรม เพราะอาจท าให

โปรแกรมหยดท างานหรอเกดหนวยความจ ารวไหล (Memory Leak) ได

มาโครและชนดขอมลทส าคญใน Microsoft Visual C++

การเขยนโปรแกรมดวย Visual C++ มชนดขอมลทมการนยามไวแลว เพอใหสะดวกตอการใช

งาน มาโครและชนดขอมลทส าคญมดงน

มาโคร/ชนดขอมล รายละเอยด

_tmain _tmain จะถกเปลยนเปน wmain ถามการนยาม _UNICODE ซงใชส าหรบ

โปรแกรมทตองการใชรหส Unicode

_tmain จะถกเปลยนเปน main ถาไมมการนยาม _UNICODE

Page 7: VC-BookExample

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;

Page 8: VC-BookExample

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

Page 9: VC-BookExample

VII

ค าน า

หนงสอเลมน เขยนขนจากประสบการณของผเขยนทไดพฒนาโปรแกรมและ

ท าวจย ในเรองทเกยวของกบงานดานการค านวณ เชน การประมวลผลภาพ การท า

คอมพวเตอรกราฟก และการจ าลองการท างานของระบบ เปนตน ซงลวนแลวแตตอง

อาศยการเขยนโปรแกรมดวยภาษาทมประสทธภาพสง ท างานไดเรว และมโอเวอร

เฮดต า ซงหนงในภาษาทเหมาะสมส าหรบงานค านวณคอ Visual C++

การเขยนโปรแกรมดวย Visua l C ++ นกพฒนาตองเขาใจเทคนคการเขยน

โปรแกรมหลายอยาง เชน ตวช ตวแปรอางอง ตวชฟงกชน การเขยนโปรแกรมเชง

วตถ และการเขยนโปรแกรมเชงเหตการณ เปนตน จงจะท าใหนกพฒนาสามารถ

เขยนโปรแกรมเพอใหบรรลวตถประสงคตามทตองการ

ส าหรบต าราเลมน ผเขยนไดขามสวนทเปนพนฐานการเขยนโปรแกรมดวย

ภาษาซ โดยเนนเฉพาะสวนทส าคญทตองใชในการเขยนโปรแกรมดวย Visual C++

ดงนนต าราเลมนจงเหมาะส าหรบนกพฒนาทเขาใจภาษา C/C++ อยแลว และเคย

เขยนโปรแกรมดวย Visual C++ มาบาง ผอานควรศกษาต าราเลมอนทเปนพนฐาน

การเขยนโปรแกรมประกอบดวย ซงจะชวยใหเขาใจไดมากยงขน

ผเขยนหวงเปนอยางยงวา ต าราเลมน จะเปนทงหนงสอประกอบการเรยนการ

สอน และหนงสออางองดวย หากนกพฒนาเพยรพยายามทจะศกษาการเขยน

โปรแกรมดวย Visual C++ อยางตงใจ สกวนนกพฒนาจะเหนวา Visual C++ เปน

เครองมอในการเขยนโปรแกรมทมประสทธภาพสงมาก และ Visual C++ จะไมมวน

ตายไปจากโลกของการเขยนโปรแกรมบนวนโดวส เนองจากโปรแกรมในทางการคา

(Commercial Application) สวนใหญถกเขยนขนมาโดย Visual C++ ทงสน

ดร.สนน ศรสข, เมษายน 2551

Page 10: VC-BookExample

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

Page 11: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย Visual C++

C+

+ C

++

C

++

C+

+

IX

กตกรรมประกาศ

ผเขยนขอขอบคณ นางมรกต ศรสข ทชวยตรวจทานหนงสอและแกไขค าผด และนกศกษา

วชา การเขยนโปรแกรมเชงเหตการณ ทชวยหาทผดในหนงสอ

ขอขอบคณ ผศ.ดร. ธนวา ศรประโมง ทใหค าแนะน า การวางโครงของหนงสอ และความ

เหมาะสมของเนอหาในหนงสอเลมน

Page 12: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 13: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 14: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 15: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 16: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 17: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 18: VC-BookExample

การเขยนโปรแกรมบนวนโดวสดวย 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

Page 19: VC-BookExample

Chapter

1 บทท

เนอหาบทท 1

การเขยนโปรแกรมดวยภาษา C++

ลกษณะเดนของภาษา C++

หนวยความจ าและการใชงาน

ตวแปรแบบอางอง

การเขาถงโดยออมแบบสองตอ

ฟงกชนและตวชฟงกชน

ฟงกชนอนไลน

ฟงกชนโอเวอรโหลด

ตวชชนด void

การใชชนดขอมล* และชนดขอมล&

Part I

การเขยนโปรแกรมดวย

C++ เบองตน

Page 20: VC-BookExample

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++

□ รบทราบหลกการในการใชหนวยความจ าอยางถกตอง

□ เลอกใชฟงกชนในรปแบบตางๆ ทเหมาะสมส าหรบแตละงานได

Page 21: VC-BookExample

บทท 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 เกบขอมลลงใน

Page 22: VC-BookExample

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 เปนอย

Page 23: VC-BookExample

บทท 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++ มดงน

Page 24: VC-BookExample

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) );

Page 25: VC-BookExample

บทท 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

กจะถกเรยกใชงานทนท โดยไมมการท างานทางตรรกะ ท าใหการท างานเรวมากขนกวาเดม

โปรแกรมเชงเหตการณ การท างานบนระบบปฏบตการไมโครซอฟทวนโดว เปนการท างาน

แบบหลายงาน ดงนนงานแตละงานจะเกดขนไมพรอมกน และไมเรยงตามล าดบ เชน การวาดหนาจอ

Page 26: VC-BookExample

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

Page 27: VC-BookExample

บทท 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/

Page 28: VC-BookExample

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)

เมอฟงกชนใดถกเรยกใชโดยฟงกชนหนง ฟงกชนทถกเรยกใชจะตองคนการท างานกลบไปยงจดท

ถกเรยกใชเมอท างานเสรจแลว ซงคาต าแหนงหนวยความจ าทตองคนกลบจะถกพชไวในสแตก เมอ

เรมตนท างาน แลวจะถกพอปออกจากสแตกเมอจบการท างานของฟงกชน หากฟงกชนทถกเรยกใช

Page 29: VC-BookExample

บทท 1 การเขยนโปรแกรมดวย C++ เบองตน

11

C+

+ C

++

C

++

C+

+

Part I: Basic Idea & Concept

1

ไปเรยกใชฟงกชนอน ฟงกชนทเรยกใช กจะตองพชคาต าแหนงหนวยความจ าทตองการสงกลบ ไป

ไวในสแตกของฟงกชนทจะเรยกใช ซงการท างานจะถกสงตอไปยงฟงกชนทถกเรยกใช และจะคน

การท างานกลบมายงผทเรยกฟงกชนเปนทอดๆ ไป ซงท าใหความสามารถในการท าฟงกชนเรยก

ตนเอง (Recursive Function) สามารถท าไดดวยกลไกแบบน ดงแสดงในรปท 1-2 หากฟงกชน A ถก

เรยกใชโดยฟงกชน B สแตกของฟงกชน A จะอยดานบน และจะพชคาต าแหนงหนวยความจ าท

ตองการสงกลบการท างานมายงฟงกชน B ไปเกบไวทสแตกของฟงกชน A ดงนนเมอฟงกชน A

ท างานเสรจสน กจะพอปขอมลออกมาจนกระทงได ต าแหนงหนวยความจ าสงกลบ กจะกระโดด

กลบไปยงต าแหนงหนวยความจ านน

เมอฟงกชนสนสดการท างาน ฟงกชนจะถกน าออก (Unload) จากหนวยความจ า รวมทงขอมล

ในสแตกดวย ซงท าใหฟงกชนอนๆ สามารถใชหนวยความจ า ณ ต าแหนงนนได ดงนนหนวยความจ า

จะถกน ามาใชซ า ท าใหตวแปรแบบโลคอล ซงถกสรางในฟงกชน ไมสามารถจะน าไปใชไดอก

หลงจากฟงกชนจบการท างานไปแลว หรออาจสรปไดวาวงจรชวตของตวแปรแบบโลคอลจะเกด

และตายพรอมกบฟงกชนนนเอง

ฮพเปนหนวยความจ าทสงวนใวใหโปรแกรมใชงาน ส าหรบเปนหนวยความจ าชวคราว ซง

หนวยความจ าทถกขอจองและขนาดของมน อาจจะไมทราบไดจนกวาโปรแกรมนนจะถกสงให

ท างาน โปรแกรมทถกเรยกใชงานสามารถขอจองหนวยความจ าทวางอยได และใชงานในพนททถก

จอง หลงจากใชงานเสรจแลวกสามารถขอยกเลกหนวยความจ าสวนนนได

□ ฮพเปนพนทหนวยความจ าสวนทเหลอของโปรแกรมทงหมด

□ โปรแกรมเกบขอมลไวทฮพ โดยทขอมลจะตองคงอย แมวาฟงกชนทหอหมชดค าสงในการ

ขอจองหนวยความจ าจะจบการท างานไปแลว

□ ฮพใชเกบคาซงมวงจรชวตยาวกวาตวแปรแบบโลคอล แตสนกวาตวแปรแบบโกลบอล

□ โดยทวไปเราจะใชวธการจองหนวยความจ าแบบพลวตในการขอจองหนวยความจ าเพอใช

งาน ซงหนวยความจ าทขอจองไดจะเกบไวทฮพ

โดยทวไปหนวยความจ าจะถกขอจองและน ากลบมาใชใหม ในขณะทโปรแกรมก าลงท างาน

โดยระบบปฏบตการจะท าการจดการ และบรหารการใชหนวยความจ าใหมประสทธภาพและ

ปลอดภยมากทสด (การท างานของโปรแกรมหนง อาจจะมผลท าใหอกโปรแกรมหนงเกด

Page 30: VC-BookExample

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

Page 31: VC-BookExample

บทท 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*

Page 32: VC-BookExample

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 ไบตนนเอง

Page 33: VC-BookExample

บทท 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

Page 34: VC-BookExample

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) ตวแปรทก าหนดโดยการนยาม ชนด

ขอมล& เปนการอางองของชนดขอมลนนๆ และตองถกก าหนดคาต าแหนงหนวยความจ าตงแตเมอ

ตวแปรนนถกนยามขนมา รปแบบทวไปของการนยามตวแปรแบบอางอง เปนดงน

ขอควรคด

เราสามารถอางถงขอมลในตวชได โดยใช

รปแบบเดยวกนกบอะเรย ดงนนเราอาจสรป

ไดวา ไดมมมองของอะเรย ตวชคออะเรยท

ไมจ ากดขนาดนนเอง

Page 35: VC-BookExample

บทท 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

Page 36: VC-BookExample

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 นนเอง

Page 37: VC-BookExample

บทท 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]; ผดพลาด

Page 38: VC-BookExample

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

Page 39: VC-BookExample

บทท 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]

Page 40: VC-BookExample

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 + + ประกอบไปดวยฟงกชนและคลาส ฟงกชนเขยนขนมาเพอ

ก าหนดการท างานของงานทตองการ เชนฟงกชนในการค านวณหาพนทสเหลยม เปนตน คลาสเปน

องคประกอบหลกในการเขยนโปรแกรมเชงวตถ ซงเปนการนยามสงทตองการสรางขนมาโดยคดใน

เชงวตถ ภายในคลาสประกอบไปดวย ตวแปร และฟงกชน ซงฟงกชนเปนสวนประกอบทส าคญใน

การเขยนโปรแกรมเชงโครงสรางโมดลและเชงวตถ โดยสวนใหญน ามาใชในการแบงงาน แลวน ามา

เรยกใชภายหลง เพอความเปนระเบยบเรยบรอย อกทงเปนการชวยใหการแกไขโปรแกรมในแตละ

Page 41: VC-BookExample

บทท 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 คอชนดขอมลและชอตวแปร

สวนหวของฟงกชน

สวนตวของฟงกชน

Page 42: VC-BookExample

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 การก าหนดโปรโตไทปของฟงกชนและตวฟงกชน

โปรโตไทปของฟงกชน

Page 43: VC-BookExample

บทท 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)

เมอเราผานคาพารามเตอรเขาสฟงกชนโดยใชรปแบบสงพารามเตอรเขาในฟงกชนโดยใชคา คาทสง

เขาในฟงกชนจะมการเปลยนแปลงเฉพาะในฟงกชนเทานน ซงกลไกการท างานจะกระท าโดย การ

ส าเนาคาทสงเขามาไปเกบยงตวแปรทใชในการรบคา ซงตวแปรทใชในการรบคาจะเกบไวในสแตก

ของฟงกชนนนๆ

Page 44: VC-BookExample

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

Page 45: VC-BookExample

บทท 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 การอางถงต าแหนง

หนวยความจ า

โดยใชตวแปรแบบอางอง

Page 46: VC-BookExample

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 ใหสงคากลบ

เปนการอางอง

Page 47: VC-BookExample

บทท 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)++;

}

Page 48: VC-BookExample

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);

Page 49: VC-BookExample

บทท 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 + + จะตองจดจ าไวใหแมนวา โปรแกรมใดๆ ท

ก าลงท างานอย ระบบปฏบตการจะตองจดสรรพนทหนวยความจ าใหกบโปรแกรมนน ซงภายใน

โปรแกรมกประกอบไปดวย วตถ ฟงกชน และตวแปรตางๆ ดงนนเมอตวแปรสามารถอางถง

ต าแหนงหนวยความจ าได ฟงกชนกสามารถอางถงต าแหนงหนวยความจ าได เชนเดยวกน (วตถก

สามารถอางถงต าแหนงหนวยความจ าได) ทงนความสามารถในการอางถงต าแหนงหนวยความจ า

Page 50: VC-BookExample

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)

Page 51: VC-BookExample

บทท 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

Page 52: VC-BookExample

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

Page 53: VC-BookExample

บทท 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

Page 54: VC-BookExample

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

โดยผานตวชฟงกชน

Page 55: VC-BookExample

บทท 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) ส าหรบแตละฟงกชน ตวคอมไพลจะท าการสราง

ชดค าสงส าหรบแตละฟงกชน เมอมการเรยกใชฟงกชน การควบคมจะมาอยทฟงกชนทถกเรยกใช

Page 56: VC-BookExample

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);

}

สรางฟงกชนโดยก าหนดใหเปนอนไลน

Page 57: VC-BookExample

บทท 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));

ดงนนการเขยนมาโครจงเปนการท างานในรปแบบเดยวกนกบฟงกชนอนไลน ท าใหไมตองมการ

กระโดดไปยงฟงกชนทถกเรยกใช อยางไรกตาม การใชมาโครมอนตรายในเรองการตรวจสอบชนด

Page 58: VC-BookExample

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++)

Page 59: VC-BookExample

บทท 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)

ดงนน

Page 60: VC-BookExample

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);

}

Page 61: VC-BookExample

บทท 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*) ดงนนตวชฟงกชนทจะตองชไปยงฟงกชนใดๆ จะตองมชนดขอมลของการสง

คากลบ และพารามเตอรในฟงกชน เหมอนกนระหวางตวชฟงกชนกบฟงกชนทถกช

Page 62: VC-BookExample

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* และตวชฟงกชน

Page 63: VC-BookExample

Chapter

2 บทท

เนอหาบทท 2

คลาสและการใชงาน

ฟงกชนคอนสตรคเตอรและดสตรคเตอร

คอนสตรคเตอรปรยาย

โอเวอรโหลดคอนสตรคเตอร

โอเปอเรเตอรโอเวอรโหลด

new, this, static, friend

การสบทอดของคลาส

การท าโพลมอฟซม

ฟงกชนเวอรชวล

ซปเปอรคลาสแบบนามธรรม

การเขยนโปรแกรม

เชงวตถดวยภาษา C++

Page 64: VC-BookExample

46

บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++

C+

+ C+

+

C+

+

C+

+

วทยาศาสตรทไรศาสนา คอความพกลพการทางความคด

ศาสนาทไรวทยาศาสตร คอความมดมนอนธการของจตใจ

อลเบรต ไอนสไตน

2.1 หลกการเขยนโปรแกรมเชงวตถ

ร ปแบบการเขยนโปรแกรมแบบดงเดมเปนการแบงงานออกเปนสวนยอยหลายๆ สวน ในแตละสวนยอยกอาจแบงงานออกไปไดอก สวนยอยแตละสวนกคอโพรซเจอร ซงใชในการ

แกปญหาตามโจทยทถกก าหนดขนมา การเขยนโปรแกรมในรปแบบนเรยกวาการจ าแนกเชง

โพรซเจอร (Procedure Oriented Decomposition)

แนวคดเชงวตถ เปนรปแบบการเขยนโปรแกรมแบบใหม ทชวยใหนกพฒนาล าดบความคด

และพจารณาการสรางโปรแกรมในเชงวตถ เมอเรมสรางโปรแกรม นกพฒนาจะตองพจารณาถงตว

แปรและฟงกชนของคลาสทจะสรางขนมา อนสแตนซของคลาสคอวตถ ดงนนวตถจงสรางมาจาก

คลาสนนเอง อยางไรกตาม ตวแปรและฟงกชนในวตถทสรางมาจากคลาส อาจจะไมไดสรางขนมา

ทงหมด ขนอยกบรปแบบของการสรางคลาสนนๆ ขนมา ในแตละปญหา วตถทสรางขนมาอาจจะไม

เหมอนกน เชน ในงานดานธนาคาร วตถสามารถเปนไดตงแต บญชธนาคาร ลกคา บตรเครดต จนถง

รายการฝากถอนในแตละเดอน เปนตน วตถสามารถใชแทนสงทจบตองได หรอคดในเชงกายภาพ

เชน รายการฝากถอนในแตละเดอน หรอคดในเชงนามธรรม เชน ธรกรรม วตถทสรางขนมาจะตองม

ความสมบรณในตวเอง โดยสามารถรองรบงานทเกดขนในปญหานนๆ ได ซงการคดในเชงวตถเปน

การคดในรปแบบภาษาของปญหา (Language of Problem) ไมใชเปนปญหาของคอมพวเตอร

(Language of Computer) นนคอเมอเรานกถงการเขยนโปรแกรมเชงวตถ ตองนกถงปญหาทเกดขน

ในระบบ เชน ปญหาทเกดขนในระบบ วธการแกปญหา และตวแปรและฟงกชนทจะตองสรางขนมา

หลงจากท าความเขาใจกบเนอหาภายในบทนแลว นกศกษาจะสามารถ

□ เขาใจหลกการเขยนโปรแกรมเชงวตถดวยภาษา C++

□ น าแนวคดการเขยนโปรแกรมเชงวตถไปใชงานได

□ เรมตนการเขยนโปรแกรมดวยแนวคดเชงวตถดวยตนเองได

Page 65: VC-BookExample

บทท 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 (เขยนโปรแกรมเชงวตถ) จะเหมาะสมกบการสราง

โปรแกรมทท างานบนวนโดวส เปนตน

Page 66: VC-BookExample

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

Page 67: VC-BookExample

บทท 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;

};

ถกตอง

ผดพลาด ประกาศแลวก าหนดคาเรมตน

Page 68: VC-BookExample

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

Page 69: VC-BookExample

บทท 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 เปนเสมอนตวเชอมตอกบภายนอก ซงเปนสวนทวตถถกเรยกใช

Page 70: VC-BookExample

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:

Page 71: VC-BookExample

บทท 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 ) เปนฟงกชนทมชอเดยวกนกบคลาส โดยมนจะถกเรยกใชโดย

อตโนมตเมออนสแตนซของคลาสถกสรางขนมา

Page 72: VC-BookExample

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 ชอคลาส;

สรางวตถไวทสแตก

สรางวตถไวทฮพ

Page 73: VC-BookExample

บทท 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)

Page 74: VC-BookExample

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) {

Page 75: VC-BookExample

บทท 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); ผดพลาด

Page 76: VC-BookExample

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;

}

ฟงกชนคอนสตรคเตอร

ฟงกชนดสตรคเตอร

ท างานครงแรกครงเดยว

เมอวตถถกสราง

ท างานเมอวตถโดนท าลาย

Page 77: VC-BookExample

บทท 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;

จะสามารถสรางวตถได อยางไรกตาม เมอเราสรางฟงกชนคอนสตรคเตอรขนมาเองแลว ตวคอมไพล

จะไมสรางคอนสตรคเตอรปรยายอกตอไป ดงนนหากมการสรางฟงกชนคอนสตรคเตอรเพมโดยรบ

Page 78: VC-BookExample

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);

ซงตวคอมไพลจะสรางฟงกชนใหโดยนย มรปแบบดงน

Page 79: VC-BookExample

บทท 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;

}

Page 80: VC-BookExample

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;

};

ผดพลาด ก าหนดคาไมได

ผดพลาด ก าหนดคาไมได

ผดพลาด ก าหนดคาไมได

Page 81: VC-BookExample

บทท 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 หนวยขอมล ซงไมสามารถเกบลงในสแตกไดอยางเพยงพอ

ดงนนโปรแกรมสามารถคอมไพลได แตหากสงใหโปรแกรมท างาน จะเกดขอผดพลาดในการใชงาน

Page 82: VC-BookExample

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

อนง ต าแหนงหนวยความจ าทขอจอง จะไมเรยง

ตอเนองกน โดยต าแหนงทขอจองได จะขนอยกบ

พนทวางในหนวยความจ า

Page 83: VC-BookExample

บทท 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 จากนนน ามารวมกนโดยใชตวด าเนนการ + ซงเปนการน า

Page 84: VC-BookExample

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

+ - * / << >>

Page 85: VC-BookExample

บทท 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

Page 86: VC-BookExample

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

Page 87: VC-BookExample

บทท 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++;

Page 88: VC-BookExample

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 == &param) return true;

else return false;

}

int _tmain(int argc, _TCHAR* argv[]) {

สรางตวด าเนนการ * เรยกใช

โดย c = a * 2;

สรางตวด าเนนการ * เรยกใช

โดย c = a * 2.9;

ตวอยางท 2-4 การใชตวชเพอตรวจสอบต าแหนงหนวยความจ าของวตถ

Page 89: VC-BookExample

บทท 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

Page 90: VC-BookExample

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 จากคลาสโดยตรงโดยใชค าสง

Page 91: VC-BookExample

บทท 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 โดยปรยาย

Page 92: VC-BookExample

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

Page 93: VC-BookExample

บทท 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

Page 94: VC-BookExample

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;

Page 95: VC-BookExample

บทท 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 สมาชก

Page 96: VC-BookExample

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 ดงนนการถายทอดคณลกษณะจากซเปอรคลาสจงชวยลดงานในการเขยน

โปรแกรมลงไปไดมาก

Page 97: VC-BookExample

บทท 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

Page 98: VC-BookExample

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)

Page 99: VC-BookExample

บทท 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)

Page 100: VC-BookExample

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 คลาสพนกงาน

Page 101: VC-BookExample

บทท 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;

ดงชอมาแสดง

แสดงรายได

Page 102: VC-BookExample

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 คลาสผจดการ

Page 103: VC-BookExample

บทท 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

Page 104: VC-BookExample

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 โดยกระท าผาน ::

เรยกใชฟงกชนคอนสตรค

เตอรของซเปอรคลาส

Page 105: VC-BookExample

บทท 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

Page 106: VC-BookExample

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

Page 107: VC-BookExample

บทท 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 แลว จะได

Page 108: VC-BookExample

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

Page 109: VC-BookExample

บทท 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 การใชตวชของซเปอรคลาสชไปยงอนสแตนซของสบคลาส

Page 110: VC-BookExample

92

บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++

C+

+ C+

+

C+

+

C+

+

CTriangle tri;

CPolygon * ppoly1 = &rect;

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 = &rect;

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

Page 111: VC-BookExample

บทท 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 น าหนาฟงกชน

Page 112: VC-BookExample

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()

Page 113: VC-BookExample

บทท 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 = &rect;

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

Page 114: VC-BookExample

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:

Page 115: VC-BookExample

บทท 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;

ฟงกชนเวอรชวลบรสทธ

Page 116: VC-BookExample

98

บทท 2 การเขยนโปรแกรมเชงวตถดวยภาษา C++

C+

+ C+

+

C+

+

C+

+

แบบฝกหดทายบท

1. จงเปรยบเทยบขอแตกตางระหวางคลาสและสตรคเจอร วามขอดขอเสยตางกนอยางไร

2. จงอธบายประโยชนในการใชงานฟงกชนคอนสตรคเตอรและฟงกชนดสตรคเตอร

3. หากตองการเขยนโปรแกรมเพอวาดภาพเปนบลอกไดอะแกรม จงออกแบบคลาสทมในระบบ

4. หากตองการเขยนโปรแกรมใหวาดรปทรงไดทกรปแบบ แตใหมค าสงในการเรยกใชฟงกชน

OnPaint ของวตถเพยงชดเดยว เราตองใชความสามารถใดของการเขยนโปรแกรมเชงวตถ

5. หากตองการใชวตถสองตวสามารถกระท าตวด าเนนการทางคณตศาสตรได เชน + - จงเขยนคลาส

CMyDate เพอใหสามารถ + - กนได

6. จงอธบายขอดในการสบทอด ในการเขยนโปรแกรมเชงวตถ

7. หากตองการเขาถงสมาชกของคลาสแบบ private และ protected จากภายนอก เราสามารถใชกลไก

การท างานแบบใด จงอธบาย

8. สมาชกของซปเปอรคลาสใดบางทไมไดถกถายทอดไปยงสบคลาส จงอธบาย

9. จงอธบายความหมายของชนดของคลาสทเขากนได

10. จงอธบายความแตกตางระหวางสมาชกแบบ public protected และ private