Trình bày chương 6 trong cuốn Thinking in C++
Sư khơi tao va sư giai phong :
1. Bao đam sư tao lâp ban đâu băng ham khơi tao.
2. Bao đam sư giai phong băng ham huy.
3. Sư loai bo cua khôi đinh nghia trong :
- vong lăp.
- Sư câp phat bô nhơ lưu trư.
4. STASH vơi ham tao va ham huy.
4. STACK vơi ham tao va ham huy.
5. Gôp chung sư khơi tao.
6. Nhưng ham khơi tao măc đinh.
7. Kêt luân.
ma ca struct Link cung co. //: C06:Stack3. cpp {O} // Constructors/destructors #include "Stack3. h" #include ". . /require. h" using namespace std; Stack::Link::Link(void* dat, Link* nxt) { data = dat; next = nxt; } Stack::Link::~Link() { } Stack::Stack() { head = 0; } void Stack::push(void* dat) { head = new Link(dat,head); }void* Stack::peek() { require(head != 0, "Stack empty"); return head->data; } void* Stack::pop() { if(head == 0) return 0; void* result = head->data; Link* oldHead = head; head = head->next; delete oldHead; return result; } Stack::~Stack() { require(head == 0, "Stack not empty"); } ///:~ Ham khơi tao Link::Link đơn gian chi khơi tao data va con tro next, nên trong Stack::Push dong head = new Link(dat,head); không chi phân phôi môt link mơi ma con khơi tao con tro cho link đo. Tai sao ham huy cua link lai không lam gi ca – cach cu thê, tai sao no không delete con tro data ? Co 2 vân dê. Bơi vi ta không thê delete môt con tro void nêu như no tro tơi môt đôi tương. Hơn nưa, nêu ham huy link xoa con tro data, ham pop() se kêt thuc viêc tra vê môt con tro tro tơi môt đôi tương bi xoa, va no se tao ra môt lôi. Điêu nay thinh thoang am chi môt vân đê cua viêc sơ hưu: Link va stack chi chưa con tro ,nhưng no không chiu trach nhiêm xoa chung. Điêu nay nghia la ban rât cân thân xem cai gi nhân trach nhiêm huy. Thi du như, nêu như ban không pop() va delete tât ca nhưng con tro trên stack,chung se không tư đông xoa bơi ham huy. Đây co le la điêu kho chiu va dân tơi sư ro ri bô nhơ, nên cân biêt cai gi chiu trach nhiêm viêc huy môt đôi tương la môt sư khac biêt giưa môt chương trinh thanh công va môt chương trinh co lôi – Đo la li do tai sao stack::~stack in ra môt thông bao lôi nêu như đôi tương stack không rông khi huy : Stack::~Stack() { require(head == 0, "Stack not empty"); } Ham require đươc khai bao trong header file require. h đươc dung đê xem lôi, thay vi dung ham assert() trong header . Cu phap : require(expr, thông bao lôi); Nêu biêu thưc expr tra vê gia tri 0, thi ham se hiên thi thông bao lôi. Bơi vi sư phân phôi va huy bô nhơ cua đôi tương link đươc ân chưa trong stack, ban không thây no xay ra trong chương trinh khac măc dâu ban chiu trach nhiêm xoa con tro tư ham pop(): //: C06:Stack3Test. cpp //{L} Stack3 //{T} Stack3Test. cpp // Constructors/destructors #include "Stack3. h" #include ". . /require. h" #include #include #include using namespace std; int main(int argc, char* argv[]) { requireArgs(argc, 1); // File name is argument ifstream in(argv1]); assure(in, argv[1]); Stack textlines; string line; // Read file and store lines in the stack: while(getline(in, line)) textlines. push(new string(line)); // Pop the lines from the stack and print them: string* s; while((s = (string*)textlines. pop()) != 0) { cout << *s << endl; delete s; } } ///:~ Trong trương hơp nay tât ca nhưng dong trong textlines se đươc xay ra va xoa, nhưng nêu chung không đươc lam vây ta se đưa ra môt thông điêp require() thông bao bô nhơ bi lô hông. 6. GÔP CHUNG SƯ KHƠI TAO: Khai niêm nay am chi viêc kêt hơp nhiêu loai dư liêu vơi nhau, giông như struct va class. Môt mang la môt sư gôp chung kiêu dư liêu duy nhât. Sư khơi tao gia tri cho tâp hơp co thê dê gây ra lôi va sư dai dong. Viêc gôp chung sư khơi tao cua C++ lam no thêm chăc chăn hơn. Khi ta tao môt đôi tương băng viêc gôp chung chung lai, tât ca nhưng gi ta phai lam la tao ra môt phep gan, va viêc khơi tao se đươc chu y bơi trinh biên dich. Tinh chât cua no phu thuôc vao kiêu cua tâp ma ta giai quyêt ,nhưng trong tât ca trương hơp ma nhưng thanh phân nay đươc gan phai đươc bao quanh bơi dâu ngoăc xoăn. Đây la vi du cho môt mang: int a[5] = { 1, 2, 3, 4, 5 }; Nêu như ta thư đưa ra nhiêu sư khơi tao hơn nhưng thanh phân trong mang, bô biên dich se thông bao lôi. Nhưng điêu gi se xay ra nêu như ta đưa ra it sư khơi tao hơn. vi du như: int b[6] = {0}; Ơ đây trinh biên dich se dung gia tri khơi tao đâu tiên cho thanh phân đâu tiên cua mang, va sau đo dung zero cho tât ca nhưng thanh phân con lai va không đươc khai bao. Chu y răng hanh vi khơi tao se không xay ra nêu như ta xac đinh môt mang ma không co danh sach khơi tao. Biêu thưc ơ trên la môt cach ngăn gon đê khơi tao môt mang băng zero ma không dung ham lâp for ma không gây ra bât cư lôi nao. Môt cach ngăn gon thư hai cho mang la automatic counting, trong đo ban đê cho trinh biên dich xac đinh kich thươc cua mang dưa trên khôi lương cua cac khơi tao: int c[] = { 1, 2, 3, 4 }; Bây giơ nêu như ta quyêt đinh thêm môt thanh phân khac vao mang, ta chi đơn gian thêm môt khơi tao khac. Nêu như ta co thê thuyêt lâp đươc code cua minh sao cho ma no cân phai đươc thay đôi trong môt hoan canh xâu nao đo. Ta co thê giam đươc phat sinh lôi trong viêc sưa đôi. Nhưng băng cach nao ta xac đinh đươc kich thươc cua mang? Biêu thưc: sizeof c / sizeof *c ( kich thươc cua toan bô mang chia cho kich thươc cua phân tư đâu tiên ) la môt thu thuât đê không cân phai sưa đôi nêu như kich thươc cua mang thay đôi: for(int i = 0; i < sizeof c / sizeof *c; i++) c[i]++; Bơi vi câu truc cung la môt khôi tâp hơp, nên chung co thê đươc khơi tao băng cach tương tư. Bơi vi struct cua C co tât ca cac thanh viên la kiêu public, nên no co thê đươc gan trưc tiêp: struct X { int i; float f; char c; }; X x1 = { 1, 2. 2, 'c' }; Nêu như ta co môt mang nhưng đôi tương như vây, ta co thê khơi tao chung băng cach dung môt tâp hơp lông vao nhau cua nhưng dâu ngoăc moc cho môi đôi tương: X x2[3] = { {1, 1. 1, 'a'}, {2, 2. 2, 'b'} }; Ơ đây, đôi tương thư 3 đươc khơi tao băng zero. Nêu như moi thanh viên dư liêu la private ( đo la môt trương hơp đăc trưng cho thiêt kê lơp trong C++ ), hoăc kê ca moi thư la public nhưng la môt ham khơi tao. Trong vi du trên, nhưng khơi tao đươc gan trưc tiêp cho nhưng phân tư cua môt tâp hơp, nhưng ham khơi tao la môt cach cua viêc ep buôc sư khơi tao xay ra thông qua môt giao diên chinh thưc. Ơ đây ham khơi tao phai đươc goi đê diên ta sư khơi tao. Nêu như ta co môt struct như dươi đây : struct Y { float f; int i; Y(int a); }; Ta phai chi ra ham khơi tao. Sư tiêp cân tôt nhât đươc trinh bay dươi đây: Y y1[] = { Y(1), Y(2), Y(3) }; Ta co đươc 3 đôi tương va 3 ham khơi tao đươc goi. Bât cư khi nao ta co môt ham khơi tao đươc goi, cho du no la môt struct vơi tât ca môt thanh viên public hay la class vơi kiêu dư liêu thanh viên private, tât ca sư khơi tao phai thông qua ham khơi tao kê ca khi no dung sư khơi tao gôp chung. Đây la môt vi du thư hai chi ra ham khơi tao đa tham sô: //: C06:Multiarg. cpp // Multiple constructor arguments // with aggregate initialization #include using namespace std; class Z { int i, j; public: Z(int ii, int jj); void print(); }; Z::Z(int ii, int jj) { i = ii; j = jj; } void Z::print() { cout << "i = " << i << ", j = " << j << endl; } int main() { Z zz[] = { Z(1,2), Z(3,4), Z(5,6), Z(7,8) }; for(int i = 0; i < sizeof zz / sizeof *zz; i++) zz[i]. print(); } ///:~ Chu y răng no giông như la ham khơi tao đươc goi cho môi đôi tương trong mang. 7. SƯ KHƠI TAO MĂC ĐINH: Sư khơi tao măc đinh co thê đươc goi ma không co tham sô. Môt ham khơi tao măc đinh dung đê tao môt “ vanilla object ” ,nhưng no cung quan trong khi trinh biên dich đươc bao la tao môt đôi tương ma không đưa ra bât ki môt chi tiêt nao. Vi du nêu như ta lây môt struct Y đươc đinh nghia luc trươc va dung no trong môt sư xac đinh như sau : Y y2[2] = { Y(1) }; Trinh biên dich se phan nan no không tim thây môt ham khơi tao măc đinh. Đôi tương thư hai trong mang muôn đươc tao ma không co tham sô, va đo la luc ma trinh biên dich dung tơi ham khơi tao. Thưc ra, ban co thê đơn gian xac đinh môt mang đôi tương Y như dươi đây, Y y3[7]; Trinh biên dich se phan nan vi no phai co môt ham khơi tao măc đinh đê khơi tao môi đôi tương trong mang. Vân đê tương tư xay ra nêu như ta tao ra môt đôi tương như sau : Y y4; Nhơ răng, nêu ta co môt ham khơi tao, trinh biên dich đam bao răng sư khơi tao luôn xay ra, bât châp bât ki tinh huông nao. Ham khơi tao măc đinh thi qua quan trong, nên nêu ( va chi nêu ) không co ham khơi tao trong môt câu truc ( struct hay class ), trinh biên dich se tư đông tao môt cai cho ban. //: C06:AutoDefaultConstructor. cpp // Automatically-generated default constructor class V { int i; // private }; // No constructor int main() { V v, v2[10]; } ///:~ Nêu bât ki ham khơi tao nao đươc xac đinh, tuy nhiên, va không co ham khơi tao măc đinh, thi thê hiên cua V ơ trên se sinh ra lôi biên dich. Ban co thê nghi trinh biên dich – ham khơi tao tông hơp nên lam môt vai sư khơi tao thông minh, như thiêt lâp tât ca gia tri cua đôi tương la zero. Nhưng không phai vây – no se vươt ra khoi sư điêu khiên cua ngươi lâp trinh. Nêu như ta muôn bô nhơ đươc khơi tao tơi zero, ta phai tư lam điêu đo băng cach viêt ham khơi tao măc đinh. Dâu cho trinh biên dich tao môt ham khơi tao măc đinh cho ban, hanh vi cua trinh biên dich – ham khơi tao tông hơp hiêm khi đươc như ban muôn. Noi chung, ta nên xac đinh ham khơi tao môt cach ro rang va không cho phep trinh biên dich lam no cho ta. 8. KÊT LUÂN: Co ve như câu truc ti mi đươc cung câp bơi C++ đưa cho ta môt gơi y rât la manh vê sư quan trong cua sư khơi tao va sư huy trong ngôn ngư nay. Môt trong nhưng nhân xet đâu tiên vê C la nhưng phân co y nghia trong nhưng vân đê đươc gây ra bơi sư khơi tao biên không đung. Nhưng lôi nay rât kho đê tim thây. Bơi vi ham khơi tao va ham huy cho phep ta đam bao sư khơi tao va sư huy hơp ly ( trinh biên dich không cho phep môt đôi tương đươc tao va huy nêu không co lơi goi ham khơi tao va ham huy hơp ly ).
File đính kèm:
- Trình bày chương 6 trong cuốn Thinking in C++.pdf