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

