+ h ' ' 5 h 8 @ ! @ % a % 0 2 # 1 2 # i - 4 %...

24
การโปรแกรมเชิงวัตถุ 1 3901-2006 นายเรวันต์ เอาทองทิพย์ หน่วยที 8 เทมเพลตและการจัดการข้อผิดพลาด (Templates and Exceptions) หัวข้อเรือง 8.1 ฟังกชันเทมเพลต (Function templates) 8.2 คลาสเทมเพลต (Class templates) 8.3 เทมเพลตพิเศษ (Template specialization) 8.4 การกาหนดคาในเทมเพลต (Parameter values for templates) 8.5 การจัดการข้อผิดพลาด (Exception Handling Fundamentals) 8.6 ข้อผิดพลาดมาตรฐาน (Standard exceptions) สาระสําคัญ ปกติการเขียนฟังกชัน หรือสร้างคลาสขึนมาจะต้องกาหนดชนิดข้อมูลทีจะใช้ในฟังกชันหรือ คลาสกอน เมือจะเปลียนชนิดข้อมูลใหม กต้องสร้างฟังกชั นหรือคลาสขึนมาใหม ทําให้เสียเวลา ใน ภาษา C++ จึงได้เตรียมเครืองมือทีแกปัญหาเรียกวาเทมเพลต (template) เทมเพลต คือ การกาหนด ชนิดข้อมูลตาง ๆ มาใช้รวมกน โดยอาศัย ฟังกชันหรือคลาส ในการ นําไปใช้ ฟังกชันทีนําไปใช้เรียกวาฟังกชันเทมเพลต และคลาสทีนําไปใช้เรี ยกวาคลาสเทมเพลต ทําให้ ฟังกชันและคลาสทีใช้เทมเพลต สามารถ ทํางานกบข้อมูลได้หลากหลายชนิด การพัฒนาโปรแกรม อาจมีข้อผิดพลาดเกดขึน ระหวางการทํางานได้ตลอดเวลา ดังนันภาษา C++ จึงมีชุดคําสังเพื ตรวจจับข้อผิดพลาดทีเกดขึน คือ คําสัง try/catch โดยใช้รวมกบกา รจัดการ ข้อผิดพลาด (exception) ในไลบรารีมาตรฐานในภาษา C++ จดประสงค์การเรียนการสอน จดประสงค์ ทัวไป (ปลายทาง) นักศึกษามีความรู้ความเข้าใจเกยวกบ ั เทมเพลตและการจัดการข้อผิดพลาด จดประสงค์เชิงพฤติกรรม (นําทาง) เมือศึกษาหน่วยนีแล้วนักศึ กษาสามารถ 1. ใช้ฟังกชัน เทมเพลตและคลาสเทมเพลตได้ 2. สร้างชนิดข้อมูลใหม่ จากเทมเพลตเดิมได้ 3. จัดการข้อผิดพลาดในภาษา C++ได้ 4. เลือกใช้ข้อผิดพลาดมาตรฐาน (Standard Exception) ในภาษา C++ได้ 5. แสดงกจนิสัยในการทํางานด้วยความประณีต รอบคอบและปลอดภัย ตระหนักถึงคุณภาพของงานและมีจริยธรรมในงานอาชีพ

Upload: others

Post on 01-Jan-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

หนวยท� 8 เทมเพลตและการจดการขอผดพลาด (Templates and Exceptions)

หวขอเร�อง 8.1 ฟงกชนเทมเพลต (Function templates) 8.2 คลาสเทมเพลต (Class templates) 8.3 เทมเพลตพเศษ (Template specialization) 8.4 การกาหนดคาในเทมเพลต (Parameter values for templates) 8.5 การจดการขอผดพลาด (Exception Handling Fundamentals) 8.6 ขอผดพลาดมาตรฐาน (Standard exceptions)

สาระสาคญ ปกตการเขยนฟงกชน หรอสรางคลาสขนมาจะตองกาหนดชนดขอมลทTจะใชในฟงกชนหรอ Uคลาสกอน เมTอจะเปลTยนชนดขอมลใหม กตองสรางฟงกช นหรอคลาสขนมาใหม ทาใหเสยเวลา ในU ภาษา C++ จงไดเตรยมเครTองมอทTแกปญหาเรยกวาเทมเพลต (template)

เทมเพลต คอ การกาหนด ชนดขอมลตาง ๆ มาใชรวมกน โดยอาศย ฟงกชนหรอคลาส ในการนาไปใช ฟงกชนทTนาไปใชเรยกวาฟงกชนเทมเพลต และคลาสทTนาไปใชเร ยกวาคลาสเทมเพลต ทาใหฟงกชนและคลาสทTใชเทมเพลต สามารถ ทางานกบขอมลไดหลากหลายชนด การพฒนาโปรแกรม อาจมขอผดพลาดเกดขน U ระหวางการทางานไดตลอดเวลา ดงนนภาษา UC++ จงมชดคาสงเพTอT ตรวจจบขอผดพลาดทTเกดขน คอ U คาสง T try/catch โดยใชรวมกบกา รจดการขอผดพลาด (exception) ในไลบรารมาตรฐานในภาษา C++

จดประสงคการเรยนการสอน จดประสงค ท�วไป (ปลายทาง) นกศกษามความรความเขาใจเกยวกบT เทมเพลตและการจดการขอผดพลาด จดประสงคเชงพฤตกรรม (นาทาง) เม�อศกษาหนวยน=แลวนกศกษาสามารถ 1. ใชฟงกชน เทมเพลตและคลาสเทมเพลตได 2. สรางชนดขอมลใหม จากเทมเพลตเดมได 3. จดการขอผดพลาดในภาษา C++ได 4. เลอกใชขอผดพลาดมาตรฐาน (Standard Exception) ในภาษา C++ได 5. แสดงกจนสยในการทางานดวยความประณต รอบคอบและปลอดภย

ตระหนกถงคณภาพของงานและมจรยธรรมในงานอาชพ

Page 2: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

174

เน=อหาสาระ เทมเพลต (templates)

templates เปนสงใหมทTเสนอโดย T ANSI C++ หากคอมไพเลอรทTใชอยไมเขากนกบมาตรฐานน Uกไมสามารถจะใชได ความสะดวกทTภาษา C++ จดเตรยมไวสาหรบเทมเพลตทTสรางขน เปนหนTงในลกษณะเดนของU ภาษา C++ เหมอนกบเปนตวจกรกลสาหรบการเขยนคาสงโดยอตโนมต ซT งทาใหการปรบปรง Tโปรแกรมเปนไปอยางมป ระสทธภาพ ในบทนจะกU ลา วถงความหมายของ Templates ลกษณะของเทมเพลต ซT งมทงแบบฟงกชนและU แบบคลาส

ความหมายของเทมพลต เทมเพลต คอ การนาเอาฟงกชนหรอคลาสมาเพมความสามารถ ใหทางานกบขอมลได Tหลากหลายชนด โดยอาศยพารามเตอรเทมเพลต (Template Parameters) ซT งเปนตาแหนงทTวางสาหรบ ชนดขอมลและคลาสตาง ๆ

8.1 ฟงกชนเทมเพลต (Function templates) ฟงกชนเทมเพลต เรยกวา instances ของเทมเพลตเพTอใชกาหนดชนดขอมลของฟงกชน

รปแบบคาสงT template <class identifier> function _declaration; template <typename identifier> function _declaration; ตวอยางเพTอความเขาใจยงขน เชน หากตองการสรางฟงกชน T U เทมเพลต ใหคนคา กลบมายง

ฟงกชน สามารถทาได คอ template <class GenericType> GenericType GetMax (GenericType a, GenericType b) { return (a>b?a:b); }

GenericType หมายถงชนดขอมลทTยงไมทราบชนดของขอมล บรรทดแรก คอ การสรางชนดขอมลเรยกวา class template ชTอ GenericType

บรรทดสอง ในฟงกชน GetMax จะมพารามเตอร 2 ตว คอ a และ b ซT ง มชนดขอมลแบบ GenericType จะสง คา คนไปยง GetMax ตามเงTอนไข a>b?a:b ในฟงกชน GetMax เมTอจะทาการเรยกใชฟงกชน GetMax จะตองกาหนด ชนดขอมล ( Type )ไวกอน ซT งเรยกวา pattern ซT งมรปแบบ ดงนU Function <pattern> (parameters); ตวอยาง การเรยกใช ฟงกชน GetMax เพTอเปรยบเทยบเลขจานวนเตมสองจานวน

Page 3: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

175

ชนดขอมลทTใช int สามารถเขยนไดดงนU int x,y; GetMax <int> (x,y);

ตวอยาง ทT 8.1 การใชงาน Function templates #include <iostream> using namespace std;

template <class T> T GetMax (T a, T b) { T result; result = (a>b)? a : b; return (result); }

int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax<int>(i,j); n=GetMax<long>(l,m); cout << k << endl; cout << n << endl; return 0; }

ผลลพธ

ตวอยาง ทT 8.2 การใชงาน Function templates กรณพารามเตอรตางชนดขอมล #include <iostream> using namespace std; template <class T, class U> T GetMin (T a, U b) { return (a<b?a:b);

6 10

Page 4: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

176

} int main () { int i,j=5; long l=10; i = GetMin<int,long> (j,l); cout << i << endl; return 0; }

ผลลพธ

8.2 คลาสเทมเพลต (Class Template) เทมเพลตคลาสบางครงเรยกวา รปแบบพU ารามเตอร (Parameterized Types) เพราะสามารถ

ใชไดกบชนดขอมลใดกได และสามารถมไดหลาย ๆ พารามเตอร การประกาศคลาสเทมเพลต จะใชคาสงวน template ตามดวยลสตเทมเพลตพารามเตอร (template parameter) ภายในเครTองหมาย < > และวางหนาชTอคลาส

รปแบบทวไปT template <class T,…. Class x{…}; ตวอยาง : template <class T> class myclass {

T values [2]; public: myclass (T first, T second) {

values[0]=first; values[1]=second; } };

5

Page 5: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

177

จากตวอยาง class myclass ไดกาหนดตวแปรแบบอารเรย เกบคา 2 จานวน ถาตองการนาคาจานวนเตมไปเกบ เชน 115 และ 36 ไปเกบ จะ ตองกาหนด

myclass <int> myobject (115, 36); แตถาตองการเลขจานวนทศนยม เราตองกาหนดดงน U myclass <float> myfloats (3.0, 2.18);

ตวอยาง ทT 8.3 การใชงาน class template #include <iostream> using namespace std; template <class T> class A { T a, b; public: A (T first, T second) {a=first; b=second;} T getmax (){ T retval; retval = a>b? a : b; return retval; } }; int main () { A <int> myobject(100, 75); cout << myobject.getmax(); return 0; }

ผลลพธ

8.3 เทมเพลตพเศษ (Template specialization) ในกรณเมTอการใชเทมเพลต ในการกาหนดชนดขอมล แตตอ งการผลลพธตางกน กสามารถแยก

เทมเพลต ออกมาสรางชนดขอมลใหมดวย คาสง T template<>

100

Page 6: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

178

ตวอยาง ทT 8.4 การใชคาสง T template<> #include <iostream> using namespace std; template <class T> class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () {return ++element;} }; template <> class mycontainer <char> { char element; public: mycontainer (char arg) {element=arg;} char uppercase () { if ((element>='a')&&(element<='z')) element+='A'-'a'; return element; } }; int main () { mycontainer<int> myint (7); mycontainer<char> mychar ('j'); cout << myint.increase() << endl; cout << mychar.uppercase() << endl; return 0; }

ผลลพธ 8

J

Page 7: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

179

8.4 การกาหนดคาในเทมเพลต (Parameter values for templates) การกาหนดชนดขอมลโดยตรงในเทมเพลต เรยกวา nontype parameters เปนการกาหนดเปนคา

ในการเรมตนในเทมเพลตT โดยมรปแบบเทมเพลต ดงตวอยาง template< typename T, int elements > ซT งมการกาหน ด ชนดขอมลเปน int

ตวอยาง ทT 8.5 การใช nontype parameters กบอารเรย #include <iostream> using namespace std; template <class T, int N> class aType { T memblock[N]; public: void setmember (int x, T value); T getmember (int x); }; template <class T, int N> void aType<T,N>::setmember(int x,T value) { memblock[x]=value; } template <class T, int N> T aType<T,N>::getmember (int x) { return memblock[x]; } int main () { aType <int,5> myints; aType <float,5> myfloats; myints.setmember (0,100); myfloats.setmember (3,3.1416); cout << myints.getmember(0) << '\n'; cout << myfloats.getmember(3) << '\n'; return 0; }

Page 8: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

180

ผลลพธ

จากตวอยางใช ฟงกชน setmember กาหนด คา ใน array memblock และใชฟงกชน getmember นาคามาแสดง

8.5 การจดการขอผดพลาด (Exceptions) การพฒนาโปรแกรม อาจมขอผดพลาดทTไมถกตองเกดขนกบ U คาสงT ทTเขยน เชน หาทรพยากรทTเรยกใชไมพบ หรอ การทางานอยนอกเหนอขอจากดทT กาหนด ฯลฯ ฉะนUนการเขยนโปรแกรมทTดจะตองมการจดการขอผดพลาดทTเกดขนมา U ได การจดการขอผดพลาด (Exceptions Handling) ทTจะอธบายตอไปน เปนขอกาหนดใหมทTเสนอ Uโดยมาตรฐาน ANSI C++ หาก C++ คอมไพเลอรทTใชอยไมสนบสนน มาตรฐานนกไมอาจใชขอกาหนดU นไดU ในบทนจะกลาวถงU ชดคาสงจดการขอT ผดพลาดของโปรแกรม โดยควบคมขอผดพลาดในการทางานดวยคาสง T try, throw และ catch รวมไปถงไลบรารมาตรฐานทTเกยวกบการจดการขอผดพลาดT ของ C++ ความผดพลาดของการเขยนโปรแกรม โดยทวไปแลT วอาจแบงชนดของความผดพลาดทTเกดขนจากการเขยนโปรแกรม ไดเปน U 2 ประเภท คอ ความผดพลาดขณะคอมไพลหรอทTเรยกวา Compile-Time Errors อาจเรยกไดอกอยางวา Syntax Error และความผดพลาดขณะทาการประมวลผล หรอ Run-Time-Errors 1. ความผดพลาดขณะคอมไพล มกเกด จากการเขยนโปรแกรมไมทาตามรปแบบคาสง เชน ลม Tใส{} () เมTอจบประโยค เปนตน ลกษณะความผดพลาดแบบนU จะคนเคยกนเพราะเปนประสบการณพนฐานทTตองแกไขโปรแกรม ไมเชนนนโปรแกรมกจะไมทางานU U 2. ความผดพลาดขณะทาการประมวลผล อาจจาแนกไดเปน 2 สาเหตใหญ ๆ คอ ความผดพลาดจากวธการคด (Program Logic) และความผดพลาดทTเกดจากสภาวะทางานไมสมประกอบ

2.1 ความผดพลาดจากวธการคด การ เขยนโปรแกรมจาเปนจะตองปองกนโดยคดหาวธ การตรวจจบความผดพลาดดงกลาว ในภาษา C++ โดยใชคาสง T try, throw และ catch 2.2 ความผดพลาดทTเกดจากสภาวะการทางาน ของระบบ เชน เนตเวรกไมทางานดสกเตม เปนตน

100 3.1416

Page 9: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

181

การจดการขอผดพลาดจากวธการคด ขอผดพลาดทTเกดขนนตองทาการจดการใหได และ U U ภาษา C++ ไดรวบรวมเครTองมอทTจะจดการกบขอผดพลาดโดยทนทไว 3 คาสงT คอ try, throw และ catch รปทวไปของคาสงT T try { // statements } catch(dataType1 identifier) { // exception handling code } :: ::

catch(dataTypen identifier) { // exception handling code

} catch(…) {

// exception handling code }

ภายในสวนของคาส Tง try ประกอบดวยกลมคาสงทTอาจทาใหเกดขอผดพลาดและกรณทTม Tขอผดพลาดเกดขน คาสงในสวนของ U T try จะไมไดประมวลผล สวนคาสง T catch ประกอบดวยการระบชนดของขอผดพลาดทTเกดขนในแตละกรณ และภายใน U block จะประกอบดวย ชดคาสงทTจะจดการกบT ขอผดพลาดทTเกดขน U การทางานของ try / catch block ถาไมมขอผดพลาดเกดขนภายในประโยค U try ประโยค catch ทงหมดกจะถกมองขามไป U โปรแกรมกจะประมวลผลตอจากประโยค catch ประโยคสดทาย ถาเกดขอผดพลาดขนภายในประโยคของ U try ณ จดใดจดหนT ง ประโยคคาสงทTเหลอกT จะถกยกเลกการทางาน โปรแกรมจะคนหาประโยค catch ตามลาดบ โดยคนหาประโยค catch ทTมการนยามไวสอดคลองกบขอผดพลาดทTเกดขน โดยทTถาขอผดพลาดตรงกบพารามเตอรของประโยค U catch ใด ประโยค catch นนกจะทางาน ประโยค U catch อTน ๆ ถกมองขามไป ไมมการประมวล ผลใด ๆ ประโยค catch ประโยคสดทายทTมจดสามจดในวงเลบเปนประโยค catch สาหรบตรวจจบขอผดพลาดทวT ๆ ไป (อTน) ลองพจารณาประโยค catch ตอไปน U

Page 10: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

182

catch (int x) { // ecception handling code

} ตวแปร x คอ พารามเตอรของประโยค catch นU สวนชนดของขอมล int ของพารามเตอร x เปนการระบวาประโยค catch นจะสามารถU ตรวจจบขอผดพลาดทTมชนดขอมลเปนเลขจานวนเตม ประโยค catch แตละประโยคสามารถม พารามเตอรไดอยางมากทTสดเพยง 1 ตว เทานน U ลาดบของคาส�ง catch คาสง T catch สามารถตรวจจบขอผดพลาดทTมการกาหนดชนดของขอผดพลาดไวอยาง เฉพาะเจาะจงหรอสามารถตรวจจบขอผดพลาด โดยทกชนด ตรงสวนหวของประโยค catch จะเปนการกาหนดชนดขอผดพลาดและถาประโยค catch กาหนดเปน จดสามจด (...) แลวจะเปนการทาใหประโยค catch นนU ตรวจจบผดพลาดทกชนด เนTองจากประโยค catch ทTตรงสวนหวกาหนดเปนจดสามจด (...) สามารถตรวจจบขอผดพลาดทกประเภท ดงนนUประโยค catch นควรจะU เปนประโยค catch ประโยคสดทาย เพราะถานาประโยค catch ตามดวยจดสามจดนไปไวกอนประโยค U catch อTน ๆ จะทาใหประโยค catch อTนๆ ทTตามหลงประโยค catch ทTมจดสามจด จะไมมโอกาสไดรบการประมวลผล ตรวจจบขอผดพลาดใดๆเลย ตวอยางเชนถากาหนดใหประโยค try ตามดวยประโยค catch ดงตอไปน U

try { //ประโยคคาสงตางๆT

} catch (...) { // ประโยค catch ทT 1

//ประโยคคาสงตางๆT } catch (int x) { // ประโยค catch ทT 2

//ประโยคคาสงตางๆT }

จากประโยคคาสง T try และ catch ขางตน ประโยค catch ทT 2 catch (int x) จะไมมโอกาสไดรบการประมวลผล แมกระทงเพยงครงเดยว ประโยค U U catch นเปนเสมอนประโยคคาสงทTไมจาเปนตองม U T เพราะไมมโอกาสประมวลผลใด ๆ เลย

Page 11: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

183

การโยนขอผดพลาด ( Throwing on Exception) โดยปกตการเขยนโปรแกรม จะมการวางเงTอนไขตาง ๆ ภายในคาสงT เพTอตรวจจบขอผดพลาดทTเกดขน ในกรณทTเกดขอผดพลาดขน U U มา กจะตอง ใหโปรแกรมดาเนนการกบขอผดพลาดทTเกดขน U นUนตามคาสงทTT ไดเขยนขนมา U เรยกวา การโยนขอผดพลาด ( throwing on exception) ซT งทางานไดโดยคาสง Tthrow เมTอคาสงภายในประโยค T try เกดขอผดพลาดขนและ U มการตรวจจบขอผดพลาด ดวยประโยค catch ขอผดพลาดทTเกดขนจาเปนตองถก U ดาเนนการ โดยใชคาสง T throw รปแบบคาสง T throw โดยทวไปTคอ

throw exception ; คาสง T throw จะตามดวยนพจนซT งอาจเปนคาคงทT ตวแปรหรออ อบเจกต

การใชคาส�ง try และ catch ในโปรแกรม ตวอยางทT 8.6 แสดงการทางานของ try throw และ catch #include <iostream> using namespace std; int main () { char myarray[10]; try { for (int n=0; n<=10; n++) { if (n>9) throw "Out of range"; myarray[n]='z'; } } catch(const char *str) { cout << "Exception: " << str << endl; } return 0; } ผลลพธ

Exception: Out of range

Page 12: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

184

จากตวอยาง เปนโปรแกรมการทางานซา U และมการตรวจสอบเงTอนไข กรณเมTอ n มคามากกวา 9 ใหทาการโยนขอผดพลาดทTเกดขน U กอนทT นาคา ไปเกบไวใน อารเรย myarray อารเรย myarray กจะมคา (0-9) เมTอคาสงT throw ทางาน การทางานในสวนของ try บลอกกจะสนสดลง หลU งจากนนการUทางานจะไปยง catch บลอก (ซT งจะทางานเมTอเกดขอผดพลาดขนเทานน U U ) เมTอเสรจแลวโปรแกรมกจะทางานตอไปในทTน คอ U return 0; โดย catch จะรบเฉพาะพารามเตอรทTชนดตรงกนเทานน U บอยครงทTสามารถม U catch หลายตว (Overload) ซT งจะรบชนดพารามเตอรทTตาง ๆ กน ในกรณนจะม U catch บลอกทTเขากนกบชนดของ ขอผดพลาดเทานนทางาน U (ชนดพารามเตอรของ throw ทTโยนมาให )

ตวอยางทT 8.7 แสดงการทางานของ catch หลายตว #include <iostream> using namespace std; int main () { try { char * mystring; mystring = new char [10]; if (mystring == NULL) throw "Allocation failure"; for (int n=0; n<=100; n++) { if (n>9) throw n; mystring[n]='z'; } } catch (int i) { cout << "Exception: "; cout << "index " << i << " is out of range" << endl; } catch (const char * str) { cout << "Exception: " << str << endl;

Page 13: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

185

} return 0; }

ผลลพธ

ในกรณนจะมความเปนไปไดอยางนอย U 2 กรณ ทTสามารถเกดขนได คอ U : 1. หากการรองขอขนาดขอความ 10 ตวอกษรไมสามารถใหได คอ mystring == NULL กรณนU

ขอผดพลาดจะถกโยนผานไปส catch (const char * str) 2. หากตวชของ U mystring เกนคาทTกาหนด กรณนขอผดพลาดจะถกโยนผานไปส U catch (int i)

ซT งตรงกบพารามเตอรทTเปนเลขจานวนเตม

8.6 ขอผดพลาดมาตรฐาน (Standard Exception) ภาษา C++ มการสรางคลาสขอผดพลาด (Exception Class) เพTอจดการกบขอผดพลาดตาง ๆ คลาสขอผดพลาดทTมอยในภาษา C++ นนเปนคลาสU พนฐานทTถกสรางไวสาหรบU ตรวจจบขอผดพลาดในการทางานของโปรแกรม คลาสขอผดพลาดเหลานจะมสมาชกฟงกชน U what สมาชกฟงกชน what มหนาทTสงขอความสาหรบขอผดพลาดตาง ๆ ทTเกดขน U การกาหนดสวนหวขอโปรแกรมในการจดการขอผดพลาด (Header Files for Exception Classes)

1. ขอผดพลาดพนฐานและU bad_exception ใช <exception> 2. ขอผดพลาด bad_alloc ใช <new> 3. ขอผดพลาด bad_cast และ bad_typeid ใช <typeinfo> 4. ขอผดพลาด ios_base::failure ใช <ios> 5. ขอผดพลาดอTน ๆ ใช <stdexcept>.

แสดงขอผดพลาดมาตรฐาน (Standard Exception)

Exception: index 10 is out of range

Page 14: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

186

ในภาษา C++ มคลาสขอผดพลาด 2 คลาสทTถกสรางขนจากคลาสขอผดพลาดพนฐานสาหรบU UจดการกบขอผดพลาดทTสาคญตาง ๆ คอ logic-error และ runtime-error คลาสทง U 2 คลาสนอยในไฟล U Header ชTอ stdexcept คลาส logic-error เปนคลาสขอผดพลาดพนฐานทTจะจดการกบขอผดพลาดทางดานตรรกะ เชนU ขอผดพลาดเกยวของกบ T out-of-range หรอ การสงพารามเตอรไมถกตอง ตอนเรยกฟงกชนเปน ขอผดพลาดเกยวของกบคลาส T invalid-argument สตรงออปเจกตมขนาดทTกาหนดไวแนนอน ถา สตรงออปเจกตถกใชเกบตวอกษรเกนกวาทTกาหนด ขอผดพลาด length-error จะเกดขน ซT U งเราสามารถเรยกใชคลาสขอผดพลาด length-error ได คลาส runtime-error เปนคลาสขอผดพลาดพนฐานทTจดการกบขอผดพาดทTเกดขนในระหวางU Uการประมวลผลโปรแกรมเทานน เชน ขอผดพลาดทTเกดจากการประมวลผล U stack อาจทาใหเกดขอผดพลาดทTเรยกวา underflow หรอ overflow ซT งเรากสามารถเรยกใชคลาสขอผดพลาด underflow และ overflow ได (เปนคลาสทTสรางตอยอดมาจากคลาสพนฐาน U runtime-error)

ตวอยางทT 8.8 แสดงการทางาน standard exceptions #include <iostream> #include < stdexcept > using namespace std; class myexception: public exception { virtual const char* what() const throw() { return "My exception happened"; } } myex; int main () { try { throw myex; } catch (exception& e) { cout << e.what() << endl; } return 0; }

Page 15: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

187

ตวอยาง ทT 8.9 แสดงการใชคลาสขอผดพลาด bad-alloc #include <iostream> #include <new> using namespace std; #define SIZE 100000000 int main() { int *list[50]; try { for(int i =0; i<50 ; i++) { list[i] = new int [SIZE]; cout << "List # " << i << "of " << SIZE << "Components " << endl; } } catch (bad_alloc& objexh) { cout << "In the catch block of bad_alloc , exception : " << objexh.what() << endl; } return 0; }

สรป เทมเพลต คอ การนาเอาฟงกชนหรอคลาสมาเพมค T วามสามารถ ใหทางานกบขอมลได

หลากหลายชนด โดยอาศย พารามเตอรเทมเพลต (Template Parameters) ซT งเปนตาแหนงทTวางสาหรบ ชนดขอมลและคลาสตาง ๆ ฟงกชนเทมเพลต ทTใชกาหนดชนดขอมลของฟงกชน มรปแบบคาสงT

template <class identifier> function _declaration; การประกาศคลาสเทมเพลต จะมรปแบบ

template <class T,…. Class x{…}; การจดการขอผดพลาด ในขณะการพฒนาโปรแกรม จะใชคาสง T try/catch เพTอตรวจจบ โดยใชรวมกบการจดการขอผดพลาด (exception) รปแบบทวไปของคาสงT T try { // //ประโยคคาสงตางๆT } catch(dataType1 identifier) {// exception handling code }

Page 16: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

188

ใบงานหนวยท� 8 เทมเพลตและการจดการขอผดพลาด

จดประสงค 1. เพTอใหมความรความเขาใจเกยวกบT เทมเพลต 2. เพTอใหสามารถเขยนโปรแกรมโดยใชเทมเพลตได 3. เพTอใหมความรความเขาใจเกยวกบT จดการขอผดพลาดในภาษา C++ได

กจกรรม: การปฏบตเขยนโปรแกรมภาษา C++ โดยใชโปรแกรม Dev-C++

การทดลองท� 1 จากโปรแกรมเปนการแสดงการใช function template สาหรบพารามเตอร ทTมชนดขอมลทTแตกตางกน

#include <iostream> using namespace std; template <class type1, class type2> void myfunc(type1 x, type2 y) { cout << x << ' ' << y << '\n'; } int main() { myfunc(---(a)---);

myfunc(---(b)---); return 0; }

ผลลพธทTได

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

ตาแหนง ประโยคคาสงT ---(a)--- ---(b)---

10 I like C++ 98.6 19

Page 17: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

189

การทดลองท� 2 จากโปรแกรมเปนการแสดงการใช function template ในการสลบขอมล ทTมชนดขอมลทTแตกตางกน

#include <iostream> using namespace std; template <class X> void swapargs(X &a, X &b) { ---(a)---;

---(b)---;

---(c)---;

---(d)---;

} int main() { int i=10, j=20; double x=10.1, y=23.3; char a='x', b='z'; cout << "Original i, j: " << i << ' ' << j << '\n'; cout << "Original x, y: " << x << ' ' << y << '\n'; cout << "Original a, b: " << a << ' ' << b << '\n'; swapargs(i, j); // swap integers swapargs(x, y); // swap floats swapargs(a, b); // swap chars cout << "Swapped i, j: " << i << ' ' << j << '\n'; cout << "Swapped x, y: " << x << ' ' << y << '\n'; cout << "Swapped a, b: " << a << ' ' << b << '\n'; return 0; } ผลลพธทTได

Original i, j: 10 20 Original x, y: 10.1 23.3 Original a, b: x z Swapped i, j: 20 10 Swapped x, y: 23.3 10.1 Swapped a, b: z x

Page 18: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

190

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

ตาแหนง ประโยคคาสงT ---(a)--- ---(b)--- ---(c)--- ---(d)---

การทดลองท� 3 จากโปรแกรมเปนการแสดงการสราง template เพมเตมกรณทTใชชนดขอมลเฉพาะในTการทางานดานใดดานหนTง

#include <iostream> using namespace std; ---(a)---

class myclass { T x; public: myclass(T a) { cout << "Inside generic myclass\n"; x = ---(b)---; } T getx() { return x; } }; template <> class myclass<int> { int x; public: myclass(int a) { cout << "Inside myclass<int> specialization\n";

x = ---(c)---; } int getx() { return x; }

Page 19: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

191

}; int main() { myclass<double> d(10.1); cout << "double: " << d.getx() << "\n\n"; myclass<int> i(5); cout << "int: " << i.getx() << "\n"; return 0; }

ผลลพธทTได

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

ตาแหนง ประโยคคาสงT ---(a)--- ---(b)--- ---(c)---

การทดลองท� 4 จากโปรแกรมการจดการขอผดพลาด โดยใช try/catch และ throw ในการตรวจจบขอมล #include <iostream> using namespace std; void Xhandler(int test) { try{ if(test==0) throw test; if(test==1) throw 'a'; if(test==2) throw 123.23;

Inside generic myclass double: 10.1 Inside myclass<int> specialization int: 25

Page 20: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

192

} catch(int i) { cout << "Caught an integer\n"; } catch(...) { cout << "Caught One!\n"; } } int main() { cout << "Start\n"; Xhandler(---(a)---);

Xhandler(---(b)---);

Xhandler(---(c)---); cout << "End"; return 0; }

ผลลพธทTได

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

ตาแหนง ประโยคคาสงT ---(a)--- ---(b)--- ---(c)---

Start Caught an integer Caught One! Caught One! End

Page 21: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

193

การทดลองท� 5 จากโปรแกรมการจดการขอผดพลาด โดยใช try/catch และ throw ในการตรวจจบขอมล กรณตวหารเปน 0

#include <iostream> using namespace std; void divide(double a, double b); int main() { double i, j; do { cout << "Enter numerator (0 to stop): "; cin >> i; cout << "Enter denominator: "; cin >> j; divide(i, j); } while(i != 0); return 0; } void divide(double a, double b) { try { if(!b) ---(a)--- b;

cout << "Result: " << ---(b)--- << endl; }

---(c)--- (double b) { cout << "Can't divide by zero.\n"; } }

ผลลพธทTได

Enter numerator (0 to stop): 8 Enter denominator:0 Can't divide by zero. Enter numerator (0 to stop):

Page 22: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

194

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

ตาแหนง ประโยคคาสงT ---(a)--- ---(b)--- ---(c)---

Page 23: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

195

แบบฝกหดทายหนวยท� 8

ตอนท� 1 จงตอบคาถามตอไปน= 1. เทมเพลต (templates) คออะไร …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 2. ฟงกชนเทมเพลต (Function templates) คออะไร …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 3. คลาสเทมเพลต (Class Template) คออะไร …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 4. เทมเพลตพเศษ (Template specialization) คออะไร …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 5. นยามความแตกตางของ Function Template และ Class Template …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 6. Compile-Time Errors หมายถง …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………...

Page 24: + H ' ' 5 H 8 @ ! @ % A % 0 2 # 1 2 # I - 4 % 2bls.buu.ac.th/~s54143/19Feb27/ThaiCPlus/unit8_template.pdfภาษา C++ เหม อนกบเป นต วจ กรกลส

การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย

196

7. Run-Time Errors หมายถง …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 8. จงอธบายการทางานของ try / catch block …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 9. จงอธบายการโยนขอผดพลาด ( Throwing on Exception) …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… 10. เขยนลาดบการทางาน try, throw และ catch วามหลกการและวธการดาเนนการอยางไร …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… ……………………………………………………………………………………………………

ตอนท� 2 จงเขยนโปรแกรมในการใช เทมเพลตฟงกชน ทTคนคาเฉลTยของทกสมาชกทTอยในอารเรย โดย ฟงกชน จะรบชTอของอารเรย และจานวนสมาชกของอารเรยเปน ชนด int โดยภายในฟงกชน main( ) มการสง ชนดขอมลอารเรย เปน int,double,long และ char