+ h ' ' 5 h 8 @ ! @ % a % 0 2 # 1 2 # i - 4 %...
TRANSCRIPT
การโปรแกรมเชงวตถ 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. แสดงกจนสยในการทางานดวยความประณต รอบคอบและปลอดภย
ตระหนกถงคณภาพของงานและมจรยธรรมในงานอาชพ
การโปรแกรมเชงวตถ 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อเปรยบเทยบเลขจานวนเตมสองจานวน
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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; }
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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 เพราะไมมโอกาสประมวลผลใด ๆ เลย
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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;
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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; }
การโปรแกรมเชงวตถ 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 }
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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; }
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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
การโปรแกรมเชงวตถ 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):
การโปรแกรมเชงวตถ 1 3901-2006 นายเรวนต เอาทองทพย
194
คาส�ง จงเขยนประโยคคาสงในตาแหนงทTวาง เพTอใหโปรแกรมทางานไดสมบรณ ลงในตารางT ดานลาง และ หามเปลTยนแปลงในสวนคาสงอTน ๆ T
ตาแหนง ประโยคคาสงT ---(a)--- ---(b)--- ---(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 หมายถง …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………… …………………………………………………………………………………………………...
การโปรแกรมเชงวตถ 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