Professional Documents
Culture Documents
Chöông 2. Lớp 2
2.2. Caùc thaønh phaàn cuûa lôùp 2.2. Caùc thaønh phaàn cuûa lôùp
Moät kieåu döõ lieäu laø moät bieåu dieãn cuï theå moät khaùi nieäm Lôùp trong C++ laø caøi ñaët cuûa kieåu döõ lieäu tröøu töôïng do
trong thöïc teá. Ví duï kieåu int laø moät bieåu dieãn cuï theå cuûa ngöôøi söû duïng ñònh nghóa, cho pheùp keát hôïp döõ lieäu, caùc
khaùi nieäm soá nguyeân trong toaùn hoïc. pheùp toaùn, caùc haøm lieân quan ñeå taïo ra moät ñôn vò
Trong C++, caùc kieåu döõ lieäu coù saün (built-in data types) chöông trình duy nhaát. Caùc lôùp naøy coù ñaày ñuû öu ñieåm vaø
:int, long, float, double, char... cho pheùp kieåm tra luùc tieän lôïi nhö caùc kieåu döõ lieäu noäi taïi. Lôùp taùch rôøi phaàn
bieân dòch vaø phaùt sinh maõ chöông trình toái öu. Caùc kieåu giao dieän (chæ lieân quan vôùi ngöôøi söû duïng) vaø phaàn caøi
döõ lieäu naøy cung caáp moät giao dieän töï nhieân ñoäc laäp vôùi ñaët lôùp.
phaàn caøi ñaët. Lôùp trong C++ ñöôïc caøi ñaët söû duïng töø khoaù struct vaø
class.
Ví duï so saùnh: Xaây döïng kieåu döõ lieäu stack. Ví duï so saùnh (tt)
1. Caùch tieáp caän coå ñieån: void StackInit(Stack *ps, int sz)
// Stack1.cpp : {
//Dung cau truc va ham toan cuc ps->st = ps->top = new Item[ps->size=sz];
#include <iostream.h> }
typedef int bool; void StackCleanUp(Stack *ps)
typedef int Item; {
const bool false = 0, true = 1; delete [] ps->st;
struct Stack }
{ bool StackFull(Stack *ps)
Item *st, *top; {
int size; return (ps->top - ps->st >= ps->size);
}; }
Lôùp Lôùp
Trong lôùp moïi thaønh phaàn maëc nhieân ñeàu laø rieâng tö Phaùt bieåu:
(private) nghóa laø theá giôùi beân ngoaøi khoâng ñöôïc pheùp s.size = 100; // Bao sai
truy xuaát. Do ñoù coù söï an toaøn döõ lieäu. Seõ bò baùo sai luùc bieân dòch, nhôø ñoù traùnh ñöôïc nhöõng loãi
class Stack luùc chaïy chöông trình (run-time error) raát khoù tìm khi thöïc
{ hieän chöông trình.
Item *st, *top;
int size;
void Init(int sz) {st = top = new
Item[size=sz];}
void CleanUp() {if (st) delete [] st;}
bool Full() const {return (top - st >= size);}
bool Empty() const {return (top <= st);}
bool Push(Item x);
bool Pop(Item *px);
};
Chöông 2. Lớp 21 Chöông 2. Lớp 22
Thuoäc tính truy xuaát Ví duï veà lôùp vaø thuoäc tính truy xuaát
// Stack.h // Stack.cpp
class Stack #include "stack.h"
{
bool Stack::Push(Item x)
Item *st, *top;
int size;
{
void Init(int sz) {st = top = new Item[size=sz];} if (Full()) return false;
void CleanUp() {delete [] st;} *top++ = x;
public: return true;
Stack(int sz = 20) {Init(sz);} }
~Stack() {delete [] st;}
bool Full() const {return (top - st >= size);} bool Stack::Pop(Item *px)
bool Empty() const {return (top <= st);} {
bool Push(Item x); if (Empty()) return false;
bool Pop(Item *px); *px = *--top;
}; return true;
}
Ví duï veà lôùp vaø thuoäc tính truy xuaát Söû duïng phaïm vi truy xuaát
// he16.cpp Phaïm vi truy xuaát ñöôïc söû duïng ñuùng seõ cho pheùp ta keát
#include "stack.h" luaän: Nhìn vaøo lôùp thaáy ñöôïc moïi thao taùc treân lôùp.
void XuatHe16(long n) Ngöôøi duøng bình thöôøng coù theå khai thaùc heát caùc chöùc
{ naêng (public) cuûa lôùp.
static char hTab[] = “0123456789ABCDEF”;
Ngöôøi duøng cao caáp coù theå thay ñoåi chi tieát caøi ñaët, caûi
Stack s(8); int x;
tieán giaûi thuaät caùc haøm thaønh phaàn.
do {
s.Push(n%16);
n /= 16;
} while(n);
while(s.Pop(&x))
cout << hTab[x];
}
2.2.4 Phöông thöùc thieát laäp vaø huûy boû. Phöông thöùc thieát laäp vaø huûy boû.
Phöông thöùc thieát laäp vaø huyû boû ñöôïc xaây döïng nhaèm Coù theå coù nhieàu phieân baûn khaùc nhau cuûa phöông thöùc
muïc ñích khaéc phuïc loãi queân khôûi ñoäng ñoái töôïng hoaëc thieát laäp
khôûi ñoäng dö. Vieäc queân khôûi ñoäng ñoái töôïng thöôøng Phöông thöùc huyû boû laø haøm thaønh phaàn ñaëc bieät ñöôïc töï
gaây ra nhöõng loãi raát khoù tìm. ñoäng goïi ñeán moãi khi moät ñoái töôïng bò huyû ñi. Ngöôøi ta
Phöông thöùc thieát laäp laø haøm thaønh phaàn ñaëc bieät ñöôïc thöôøng lôïi duïng ñaëc tính treân ñeå doïn deïp ñoái töôïng.
töï ñoäng goïi ñeán moãi khi moät ñoái töôïng thuoäc lôùp ñöôïc Phöông thöùc huyû boû baét ñaàu baèng daáu ngaõ (~) theo sau
taïo ra. Ngöôøi ta thöôøng lôïi duïng ñaëc tính treân ñeå khôûi bôûi teân lôùp ñeå phaân bieät noù vôùi caùc haøm thaønh phaàn
ñoäng ñoái töôïng. khaùc.
Phöông thöùc thieát laäp coù teân truøng vôùi teân lôùp ñeå phaân Chæ coù theå coù toái ña moät phöông thöùc huyû boû.
bieät noù vôùi caùc haøm thaønh phaàn khaùc.
Phöông thöùc thieát laäp vaø huûy boû. 2.3 Caùc ñaëc tính khaùc cuûa lôùp
typedef int Item;
class Stack Töï tham chieáu
{ Haøm baïn (Friends).
Item *st, *top;
int size;
Haøm thaønh phaàn haèng (const member functions).
void Init(int sz); Thaønh phaàn tónh (static members)
void CleanUp() {delete [] st;} Con troû tôùi haøm thaønh phaàn.
public:
Stack(int sz = 20) {Init(sz);}
~Stack() {delete [] st;}
bool Full() const {return (top - st >= size);}
bool Empty() const {return (top <= st);}
bool Push(Item x);
bool Pop(Item *px);
};
Ví duï: Nhaân ma traän, khoâng duøng haøm baïn Ví duï: Nhaân ma traän, khoâng duøng haøm baïn
const int N = 4; class Matrix
class Vector {
{ double a[N][N];
double a[N]; public:
public: double Get(int i, int j) const {return a[i][j];}
double Get(int i) const {return a[i];} void Set(int i, int j, double x) {a[i][j] = x;}
void Set(int i, double x) {a[i] = x;} //...
}; };
Ví duï: Nhaân ma traän, khoâng duøng haøm baïn Ví duï: Nhaân ma traän, duøng haøm baïn
Vector Multiply(const Matrix &m, const const int N = 4;
Vector &v) class Matrix;
{ class Vector
Vector r; {
double a[N];
for (int i = 0; i < N; i++) public:
{ double Get(int i) const {return a[i];}
r.Set(i, 0); void Set(int i, double x) {a[i] = x;}
friend Vector Multiply(const Matrix &m, const Vector
for (int j = 0; j < N; j++) &v);
r.Set(i, r.Get(i)+ };
m.Get(i,j)*v.Get(j));
}
return r;
}
Ví duï: Nhaân ma traän, duøng haøm baïn Ví duï minh hoaï: Söû duïng haøm baïn
class Matrix Vector Multiply(const Matrix &m, const
{ Vector &v)
double a[N][N]; {
public: Vector r;
double Get(int i, int j) const {return a[i][j];}
void Set(int i, int j, double x) {a[i][j] = x;} for (int i = 0; i < N; i++)
friend Vector Multiply(const Matrix &m, const Vector {
&v);
};
r.a[i] = 0;
for (int j = 0; j < N; j++)
r.a[i] += m.a[i][j]*v.a[j];
}
return r;
}
Haøm thaønh phaàn haèng 2.3.3 Thaønh phaàn tónh (static members)
void main() Thaønh phaàn döõ lieäu tónh laø thaønh phaàn döõ lieäu duøng
{ chung cho moïi ñoái töôïng thuoäc lôùp.
const string Truong("DH BC TDT");
Haøm thaønh phaàn tónh laø haøm thaønh phaàn coù theå hoaït
string s("ABCdef");
ñoäng khoâng caàn döõ lieäu cuûa ñoái töôïng, noùi caùch khaùc,
s.Output();
noù khoâng caàn ñoái töôïng.
s.ToLower();
s.Output();
Ta duøng haøm thaønh phaàn tónh thay vì haøm toaøn cuïc vì
Truong.Output();
noù coù lieân quan maät thieát vôùi lôùp.
Truong.ToLower(); // Bao loi Ta coøn duøng haøm thaønh phaàn tónh ñeå taïo ñoái töôïng coù
} giaù trò traû veà cho bieát vieäc taïo ñoái töôïng coù thaønh coâng
theo nghóa luaän lyù hay khoâng.
Ví duï veà thaønh phaàn tónh: CDate Ví duï veà thaønh phaàn tónh : CDate
typedef int bool; int CDate::dayTab[][13] =
const bool false = 0, true = 1; {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
class CDate {0,31,29,31,30,31,30,31,31,30,31,30,31}
{ };
static int dayTab[][13]; int CDate::DayOfMonth(int m, int y)
int day, month, year; {
public: return dayTab[LeapYear(y)][m];
static bool LeapYear(int y) {return y%400
}
== 0 || y%4==0 && y%100 != 0;}
static int DayOfMonth(int m, int y);
bool betw(int x, int a, int b)
static bool ValidDate(int d, int m, int y); {
void Input(); return x >= a && x <= b;
}; }
Ví duï veà thaønh phaàn tónh : CDate Ví duï veà thaønh phaàn tónh: Stack
bool CDate::ValidDate(int d, int m, int y)
class Stack
{ {
return betw(m,1,12) && Item *st, *top;
betw(d,1,DayOfMonth(m,y)); int size;
} void Init(int sz);
void CDate::Input() void CleanUp() {if (st) delete [] st;}
{ public:
int d,m,y; Stack(int sz = 20) {Init(sz);}
cin >> d >> m >> y; ~Stack() {CleanUp();}
while (!ValidDate(d,m,y)) static Stack *Create(int sz);
{ bool Full() const {return (top-st >= size);}
cout << "Please enter a valid date: "; bool Empty() const {return (top <= st);}
cin >> d >> m >> y;
}
bool Push(Item x);
day = d; month = m; year = y;
bool Pop(Item *px);
} };
Ví duï veà thaønh phaàn tónh: Stack Ví duï veà thaønh phaàn tónh: Stack
Stack *Stack::Create(int sz)
// Stack.cpp
{
#include <iostream.h>
Stack *ps = new Stack(sz);
#include "stack.h"
if (!ps->st)
bool Stack::Push(Item x)
{
{
delete ps;
if (Full()) return false;
return NULL;
*top++ = x;
}
return true;
return ps;
}
}
bool Stack::Pop(Item *px)
{
if (Empty()) return false;
*px = *--top;
return true;
}
Ví duï veà thaønh phaàn tónh: Stack 2.4 Thieát laäp vaø huyû boû ñoái töôïng
void main() Ta caàn kieåm soaùt khi naøo phöông thöùc thieát laäp ñöôïc
{
goïi, khi naøo phöông thöùc huyû boû ñöôïc goïi.
Stack *ps = new Stack(50000); // khong biet tao
duoc stack khong Khi naøo ñoái töôïng thieát laäp ñöôïc goïi? Khi ñoái töôïng
Stack *pr = Stack::Create(50000); ñöôïc taïo ra.
if (!pr)
Khi naøo phöông thöùc huyû boû ñöôïc goïi? Khi ñoái töôïng bò
{ cout << "Khong the tao stack"; return; }
else huyû ñi.
pr->Push(5); // ... Thôøi gian töø khi ñoái töôïng ñöôïc taïo ra ñeán khi noù bò huyû
} ñi ñöôïc goïi laø thôøi gian soáng.
Vaäy vaán ñeà xaùc ñònh khi naøo phöông thöùc thieát laäp vaø
huyû boû ñöôïc goïi trôû thaønh:
Khi naøo ñoái töôïng ñöôïc taïo ra ?
Khi naøo ñoái töôïng bò huyû ñi ?
Thieát laäp vaø huyû boû ñoái töôïng Ñoái töôïng töï ñoäng
Thôøi gian soáng cuûa ñoái töôïng khaùc nhau tuyø thuoäc ñoái Ñoái töôïng töï ñoäng (automatic objects) laø ñoái töôïng ñöôïc
töôïng ñoù thuoäc lôùp löu tröõ (storage class) naøo. Trong C++ töï ñoäng sinh ra vaø töï ñoäng bò huyû ñi.
coù caùc lôùp löu tröõ sau: Ñoái töôïng ñòa phöông
auto • Laø caùc bieán ñöôïc khai baùo, ñònh nghóa beân trong moät khoái.
global • Noù ñöôïc töï ñoäng sinh ra khi chöông trình thöïc hieän ngang doøng
static leänh chöùa ñònh nghóa vaø bò huyû ñi sau khi chöông trình hoaøn taát
free stored khoái chöùa ñònh nghóa ñoù.
Ta seõ laàn löôït xeùt caùc loaïi sau: Khi khôûi ñoäng moät ñoái töôïng baèng moät ñoái töôïng cuøng
Ñoái töôïng töï ñoäng kieåu, cô cheá taïo ñoái töôïng maëc nhieân laø sao cheùp töøng
Ñoái töôïng toaøn cuïc bit, do ñoù ñoái töôïng ñöôïc khôûi ñoäng seõ chia seû taøi
Ñoái töôïng tónh nguyeân vôùi ñoái töôïng nguoàn.
Ñoái töôïng ñöôïc caáp phaùt ñoäng
Ñoái töôïng thaønh phaàn
Ñoái töôïng laø tham soá truyeàn baèng giaù trò Ñoái töôïng laø tham soá truyeàn baèng giaù trò
int String::Compare(String s) const Khi thöïc hieän ñoaïn chöông trình treân, ta ñöôïc xuaát lieäu
{ (coù theå thay ñoåi ôû nhöõng laàn thöïc hieän khaùc nhau hoaëc
return strcmp(p,s.p); ôû maùy khaùc):
} delete 0x0f34
void main() a > b
{ delete 0x0f34
String a("Nguyen Van A"); delete 0x0f22
String b("Le Van Be");
int c = a.Compare(b);
cout << (c > 0 ? "a > b" : c == 0 ? "a =
b" : "a < b") << "\n";
}
Ñoái töôïng laø giaù trò traû veà Ñoái töôïng laø giaù trò traû veà
extern char *strdup(const char *s); String String::UpCase() const
class String {
{ String r = *this;
char *p; strupr(r.p);
public: return r;
String(char *s = "Alibaba") {p = strdup(s);} }
~String() {cout << "delete "<< (void *)p << "\n"; void main()
delete [] p;} {
void Output() const {cout << p;} clrscr();
int Compare(String s) const; String a("Nguyen Van A");
String UpCase() const; cout << "a = "; a.Output(); cout << "\n";
}; String A;
A = a.UpCase();
cout << "a = "; a.Output(); cout << "\n";
cout << "A = "; a.Output(); cout << "\n";
}
Ñoái töôïng laø giaù trò traû veà Ñoái töôïng laø giaù trò traû veà
Khi thöïc hieän ñoaïn chöông trình treân, ta ñöôïc xuaât lieäu Caùc loãi sai gaây ra ôû ñoaïn chöông trình treân do sao cheùp
a = Nguyen Van A ñoái töôïng (phaùt bieåu String r = *this), ñoái töôïng giaù trò traû
delete 0x0f36 veà vaø pheùp gaùn (A = a.Upcase).
delete 0x0f36
Ta coù theå khaéc phuïc loãi gaây ra do pheùp gaùn baèng caùch
a = 2¤2¤EN VAN A
A = 2¤2¤EN VAN A
thay hai phaùt bieåu khai baùo A vaø gaùn baèng phaùt bieåu
delete 0x0f36 khôûi ñoäng:
delete 0x0f36 String A = a.UpCase();
Null pointer assignment
Ñoái töôïng giaù trò traû veà laø baûn sao cuûa bieåu thöùc traû veà.
Do ñoù coù söï chia seû taøi nguyeân (SAI).
Ñoái töôïng laø giaù trò traû veà Ñoái töôïng laø giaù trò traû veà
void main() Xuaát lieäu trong tröôøng hôïp naøy laø
{ a = Nguyen Van A
clrscr();
delete 0x0d32
String a("Nguyen Van A");
cout << "a = "; a.Output(); cout << "\n"; a = NGUYEN VAN A
String A = a.UpCase(); A = NGUYEN VAN A
cout << "a = "; a.Output(); cout << "\n"; delete 0x0d32
cout << "A = "; a.Output(); cout << "\n"; delete 0x0d32
}
Null pointer assignment
Phöông thöùc thieát laäp baûn sao Phöông thöùc thieát laäp baûn sao
Caùc loãi sai neâu treân gaây ra do sao cheùp ñoái töôïng, ta coù Phöông thöùc thieát laäp baûn sao thöïc hieän sao cheùp theo
theå khaéc phuïc baèng caùch “daïy” trình bieân dòch sao nghóa logic, thoâng thöôøng laø taïo neân taøi nguyeân môùi (sao
cheùp ñoái töôïng moät caùch luaän lyù thay vì sao cheùp töøng cheùp saâu).
bit theo nghóa vaät lyù. Ñieàu ñoù ñöôïc thöïc hieän nhôø Phöông thöùc thieát laäp baûn sao cuõng coù theå chia seû taøi
phöông thöùc thieát laäp baûn sao. nguyeân cho caùc ñoái töôïng (sao cheùp noâng). Trong tröôøng
Phöông thöùc thieát laäp baûn sao laø phöông thöùc thieát laäp hôïp naøy, caàn coù cô cheá ñeå kieåm soaùt söû huyû boû ñoái
coù tham soá laø ñoái töôïng cuøng kieåu, duøng ñeå sao cheùp ñoái töôïng.
töôïng.
Phöông thöùc thieát laäp baûn sao Phöông thöùc thieát laäp baûn sao
extern char *strdup(const char *s); int String::Compare(String s) const
class String {
{ return strcmp(p,s.p);
char *p; }
public:
String String::UpCase() const
String(char *s = "Alibaba") {p =
{
strdup(s);} String r = *this;
String(const String &s) {p = strupr(r.p);
strdup(s.p);} return r;
~String() {cout << "delete "<< (void *)p }
<< "\n"; delete [] p;}
void Output() const {cout << p;}
int Compare(String s) const;
String UpCase() const;
};
Phöông thöùc thieát laäp baûn sao Phöông thöùc thieát laäp baûn sao
void main()
Xuaát lieäu trong tröôøng hôïp treân nhö sau:
{
delete 0x0d84
clrscr();
a > b
String a("Nguyen Van A");
a = Nguyen Van A
String b("Le Van Be");
delete 0x0d84
String aa = a;
a = Nguyen Van A
int c = a.Compare(b);
A = NGUYEN VAN A
cout << (c > 0 ? "a > b" : c == 0 ? "a =
delete 0x0d96
b" : "a < b") << "\n";
delete 0x0d72
cout << "a = "; a.Output(); cout << "\n";
delete 0x0d62
String A = a.UpCase();
delete 0x0d50
cout << "a = "; a.Output(); cout << "\n";
cout << "A = "; A.Output(); cout << "\n"; Moãi ñoái töôïng ñeàu coù taøi nguyeân rieâng neân khoâng xaûy
} tröôøng hôïp moät vuøng taøi nguyeân bò giaûi phoùng nhieàu laàn.
Phöông thöùc thieát laäp baûn sao Sao cheùp noâng vaø sao cheùp saâu
Tham soá cuûa phöông thöùc thieát laäp baûn sao baét buoäc laø Duøng phöông thöùc thieát laäp baûn sao nhö treân, trong ñoù
tham chieáu. ñoái töôïng môùi coù taøi nguyeân rieâng laø sao cheùp saâu.
Phöông thöùc thieát laäp baûn sao coù theå ñöôïc duøng ñeå sao Ta coù theå sao cheùp noâng baèng caùch chia seû taøi nguyeân
cheùp noâng, taøi nguyeân vaãn ñöôïc chia seû nhöng coù moät vaø duøng moät bieán ñeám ñeå kieåm soaùt soá theå hieän caùc ñoái
bieán ñeám ñeå kieåm soaùt. töôïng coù chia seû cuøng taøi nguyeân.
Löu yù: Khi moät ñoái töôïng thay ñoåi noäi dung, noù phaûi ñöôïc taùch
Neáu ñoái töôïng khoâng coù taøi nguyeân rieâng thì khoâng caàn ra khoûi caùc ñoái töôïng duøng chung taøi nguyeân, noùi caùch
phöông thöùc thieát laäp baûn sao. khaùc, noù phaûi coù taøi nguyeân rieâng (nhö sao cheùp saâu).
Khi truyeàn tham soá laø ñoái töôïng thuoäc lôùp coù phöông
thöùc thieát laäp baûn sao, ta neân truyeàn baèng tham chieáu
vaø coù theâm töø khoaù const.
Ví duï veà sao cheùp noâng Ví duï veà sao cheùp noâng
extern char *strdup(const char *s); class String
class StringRep {
{ StringRep *rep;
friend class String; public:
char *p; String(const char *s = "Alibaba") {rep =
int n; new StringRep(s);}
StringRep(const char *s) {p = strdup(s); n = 1;} String(const String &s) {rep = s.rep;
~StringRep() {cout << "delete ” << (void *)p <<
rep->n++;}
"\n"; delete [] p;}
};
~String();
void Output() const {cout << rep->p;}
int Compare(String s) const;
String UpCase() const;
void ToUpper();
};
Ví duï veà sao cheùp noâng Ví duï veà sao cheùp noâng
String::~String() void main()
{ {
if (--rep->n <= 0) clrscr();
delete rep; String a("Nguyen Van A");
} String b("Le Van Be");
int String::Compare(String s) const String aa = a;
{ int c = a.Compare(b);
return strcmp(rep->p,s.rep->p); cout << (c > 0 ? "a > b" : c == 0 ? "a = b" : "a
} < b") << "\n";
String String::UpCase() const cout << "a = "; a.Output(); cout << "\n";
{ String A = a.UpCase();
String r(rep->p); cout << "a = "; a.Output(); cout << "\n";
cout << "A = "; A.Output(); cout << "\n";
strupr(r.rep->p);
}
return r;
}
Ví duï veà sao cheùp noâng Ví duï veà sao cheùp noâng
Xuaát lieäu khi thöïc hieän ñoaïn chöông trình treân nhö sau:
So saùnh vôùi sao cheùp saâu: Beân traùi, duøng sao cheùp saâu, beân
a > b
phaûi duøng sao cheùp noâng.
a = Nguyen Van A
a = Nguyen Van A delete 0x0d84 a > b
A = NGUYEN VAN A a > b a = Nguyen Van A
delete 0x0d8a a = Nguyen Van A a = Nguyen Van A
delete 0x0d72 delete 0x0d84 A = NGUYEN VAN A
a = Nguyen Van A delete 0x0d8a
delete 0x0d58
A = NGUYEN VAN A delete 0x0d72
delete 0x0d96 delete 0x0d58
delete 0x0d72
delete 0x0d62
delete 0x0d50
Ví duï veà ñoái töôïng toaøn cuïc Ví duï veà ñoái töôïng toaøn cuïc
Xeùt ñoaïn chöông trình sau: Ñoaïn chöông trình ñöôïc söûa laïi nhö sau:
#include <iostream.h>
#include <iostream.h>
void main()
void main()
{
{
cout << "Hello, world.\n";
cout << "Hello, world.\n";
}
}
class Dummy
Haõy söûa laïi ñoaïn chöông trình treân ñeå coù xuaát lieäu: {
Entering a C++ program saying...
public:
Hello, world.
Dummy() {cout << "Entering a C++ program
And then exitting… saying...\n";}
Yeâu caàu khoâng thay ñoåi haøm main() döôùi baát kyø hình ~Dummy() {cout << "And then exitting...";}
thöùc naøo. }d;
Ñoái töôïng laø thaønh phaàn cuûa lôùp Ñoái töôïng laø thaønh phaàn cuûa lôùp
Ñoái töôïng coù theå laø thaønh phaàn cuûa ñoái töôïng khaùc, khi Cuù phaùp ñeå khôûi ñoäng ñoái töôïng thaønh phaàn laø duøng
moät ñoái töôïng thuoäc lôùp “lôùn” ñöôïc taïo ra, caùc thaønh daáu hai chaám (:) theo sau bôûi teân thaønh phaàn vaø tham soá
phaàn cuûa noù cuõng ñöôïc taïo ra. Phöông thöùc thieát laäp khôûi ñoäng.
(neáu coù) seõ ñöôïc töï ñoäng goïi cho caùc ñoái töôïng thaønh Khi ñoái töôïng keát hôïp bò huyû ñi thì caùc ñoái töôïng thaønh
phaàn. phaàn cuûa noù cuõng bò huyû ñi, nghóa laø phöông thöùc huyû
Neáu ñoái töôïng thaønh phaàn phaûi ñöôïc cung caáp tham soá boû seõ ñöôïc goïi cho caùc ñoái töôïng thaønh phaàn, sau khi
khi thieát laäp thì ñoái töôïng keát hôïp (ñoái töôïng lôùn) phaûi phöông thöùc huyû boû cuûa ñoái töôïng keát hôïp ñöôïc goïi.
coù phöông thöùc thieát laäp ñeå cung caáp tham soá thieát laäp
cho caùc ñoái töôïng thaønh phaàn.
Ñoái töôïng laø thaønh phaàn cuûa lôùp Ñoái töôïng laø thaønh phaàn cuûa lôùp
class Diem class String
{ {
double x,y; char *p;
public: public:
String(char *s) {p = strdup(s);}
Diem(double xx, double yy) {x = xx; y = yy;}
String(const String &s) {p = strdup(s.p);}
// ... ~String() {cout << "delete "<< (void *)p << "\n";
}; delete [] p;
class TamGiac //...
{ };
Diem A,B,C; class SinhVien
public: {
void Ve() const; String MaSo;
// ... String HoTen;
int NamSinh;
};
public:
TamGiac t; // Bao sai };
SinhVien s; // Bao sai
Ñoái töôïng thaønh phaàn - thieát laäp Khôûi ñoäng ñoái töôïng thaønh phaàn
class Diem class TamGiac
{ {
double x,y; Diem A,B,C;
public: public:
Diem(double xx, double yy) {x = xx; y = yy;} TamGiac(double xA, double yA, double xB, double
// ... yB, double xC, double yC):A(xA,yA),
}; B(xB,yB),C(xC,yC){}
void Ve() const;
// ...
};
TamGiac t(100,100,200,400,300,300);
Ñoái töôïng laø thaønh phaàn cuûa lôùp Khôûi ñoäng ñoái töôïng thaønh phaàn
class String class SinhVien
{ {
char *p; String MaSo;
public: String HoTen;
String(char *s) {p = strdup(s);} int NamSinh;
String(const String &s) {p = strdup(s.p);} public:
~String() {cout << "delete "<< (void *)p << SinhVien(char *ht, char *ms, int ns):HoTen(ht),
"\n"; delete [] p; MaSo(ms){NamSinh = ns;}
//... //...
}; };
SinhVien s(“Nguyen Van Be”, “19920005”, 1985); //Ok
Khôûi ñoäng ñoái töôïng thaønh phaàn Khôûi ñoäng ñoái töôïng thaønh phaàn
Cuù phaùp duøng daáu hai chaám cuõng ñöôïc duøng cho ñoái Cuù phaùp duøng daáu hai chaám cuõng ñöôïc duøng cho ñoái
töôïng thaønh phaàn thuoäc kieåu cô baûn. töôïng thaønh phaàn thuoäc kieåu cô baûn.
class Diem class SinhVien
{ {
double x,y; String MaSo, HoTen;
public: int NamSinh;
Diem(double xx, double yy):x(xx), y(yy){} public:
// ... SinhVien(char *ht, char *ms, int ns):HoTen(ht),
}; MaSo(ms), NamSinh(ns){}
//...
};
Ñoái töôïng thaønh phaàn - Huyû boû Ñoái töôïng laø thaønh phaàn cuûa maûng
Khi ñoái töôïng keát hôïp bò huyû boû, caùc ñoái töôïng thaønh phaàn Khi moät maûng ñöôïc taïo ra, caùc phaàn töû cuûa noù cuõng
cuûa noù cuõng bò huyû boû. ñöôïc taïo ra, do ñoù phöông thöùc thieát laäp seõ ñöôïc goïi cho
class SinhVien
{ töøng phaàn töû moät.
String MaSo, HoTen; Vì khoâng theå cung caáp tham soá khôûi ñoäng cho taát caû caùc
int NamSinh;
int SoMon; phaàn töû cuûa maûng neân khi khai baùo maûng, moãi ñoái
double *Diem; töôïng trong maûng phaûi coù khaû naêng töï khôûi ñoäng, nghóa
public: laø coù theå ñöôïc thieát laäp khoâng caàn tham soá.
SinhVien(char *ht, char *ms, int ns, int sm, double *d);
~SinhVien() {delete [] Diem;} Ñoái töôïng coù khaû naêng töï khôûi ñoäng trong caùc tröôøng
//... hôïp sau:
};
SinhVien::SinhVien(char *ht, char *ms, int ns, int sm, • Lôùp khoâng coù phöông thöùc thieát laäp.
double *d):HoTen(ht), MaSo(ms), NamSinh(ns), SoMon(sm) • Lôùp coù phöông thöùc thieát laäp khoâng tham soá.
{
memcpy(Diem = new double[SoMon], d, SoMon*sizeof(double));
• Lôùp coù phöông thöùc thieát laäp maø moïi tham soá ñeàu coù giaù trò
} maëc nhieân.
Ñoái töôïng laø thaønh phaàn cuûa maûng Ñoái töôïng laø thaønh phaàn cuûa maûng
class Diem class SinhVien
{ {
double x,y; String MaSo;
public: String HoTen;
Diem(double xx, double yy):x(xx), y(yy) {}
int NamSinh;
void Set(double xx, double yy) {x = xx, y = yy;}
// ... public:
}; SinhVien(char *ht, char *ms, int ns):HoTen(ht),
class String MaSo(ms), NamSinh(ns){}
{ //...
char *p; };
public:
String(char *s) {p = strdup(s);} String as[3]; // Bao sai
String(const String &s) {p = strdup(s.p);} Diem ad[5]; // Bao sai
~String() {cout << "delete "<< (void *)p <<
"\n"; delete [] p;} SinhVien asv[7]; // Bao sai
// ...
PTTLaäp vôùi tham soá coù giaù trò maëc nhieân PTTlaäp vôùi tham soá coù giaù trò maëc nhieân
class Diem class SinhVien
{ {
double x,y; String MaSo;
public: String HoTen;
Diem(double xx = 0, double yy = 0):x(xx), y(yy){} int NamSinh;
void Set(double xx, double yy) {x = xx, y = yy;} public:
// ... SinhVien(char *ht = “Nguyen Van A”, char *ms =
}; “19920014”, int ns =
class String 1982):HoTen(ht), MaSo(ms),
{ NamSinh(ns){}
char *p; //...
public: };
String(char *s = "Alibaba") {p = strdup(s);}
String(const String &s) {p = strdup(s.p);} String as[3]; // Ok: Ca ba phan tu deu la chuoi rong
~String() {cout << "delete "<< (void *)p << "\n"; Diem ad[5]; // Ok: ca 5 diem deu la (0,0)
delete [] p;} SinhVien asv[7]; // Ok: Het sai ca 7 sinh vien deu
// ... co cung hoten, maso, namsinh
Chöông 2. Lớp 99 Chöông 2. Lớp 100
Duøng PTTlaäp khoâng tham soá Duøng ptthieát laäp khoâng tham soá
class Diem
class SinhVien
{
double x,y; {
public: String MaSo;
Diem(double xx, double yy):x(xx), y(yy){} String HoTen;
Diem():x(0), y(0){} int NamSinh;
// ... public:
}; SinhVien(char *ht, char *ms, int ns):HoTen(ht),
class String MaSo(ms), NamSinh(ns){}
{ SinhVien():HoTen(“Nguyen Van A”),
char *p; MaSo(“19920014”), NamSinh(1982){}
public: //...
String(char *s) {p = strdup(s);} };
String() {p = strdup("Alibaba");}
String as[3]; // Ca ba phan tu deu la chuoi rong
~String() {cout << "delete "<< (void *)p << "\n";
delete [] p;} Diem ad[5]; // ca 5 diem deu la (0,0)
// ... SinhVien asv[7];// Ca 7 sinh vien deu co cung
hoten, maso, namsinh
};
Chöông 2. Lớp 101 Chöông 2. Lớp 102
Ñoái töôïng ñöôïc caáp phaùt ñoäng Ñoái töôïng ñöôïc caáp phaùt ñoäng
Ñoái töôïng ñöôïc caáp phaùt ñoäng laø caùc ñoái töôïng ñöôïc taïo class String
ra baèng pheùp toaùn new vaø bò huyû ñi baèng pheùp toaùn {
delete char *p;
public:
Pheùp toaùn new caáp ñoái töôïng trong vuøng heap (hay vuøng String(char *s) {p = strdup(s);}
free store) vaø goïi phöông thöùc thieát laäp cho ñoái töôïng String(const String &s) {p = strdup(s.p);}
ñöôïc caáp. ~String() {delete [] p;}
Duøng new coù theå caáp moät ñoái töôïng vaø duøng delete ñeå //...
huyû moät ñoái töôïng. };
class Diem
Duøng new vaø delete cuõng coù theå caáp nhieàu ñoái töôïng vaø {
huyû nhieàu ñoái töôïng. double x,y;
public:
Diem(double xx, double yy):x(xx),y(yy){};
//...
};
Chöông 2. Lớp 103 Chöông 2. Lớp
//... 104
Caáp vaø huyû moät ñoái töôïng Caáp vaø huyû nhieàu ñoái töôïng
int *pi = new int; Trong tröôøng hôïp caáp nhieàu ñoái töôïng, ta khoâng theå
int *pj = new int(15);
cung caáp tham soá cho töøng phaàn töû ñöôïc caáp:
Diem *pd = new Diem(20,40);
String *pa = new String("Nguyen Van A"); int *pai = new int[10];
//... Diem *pad = new Diem[5]; // Bao sai
delete pa; String *pas = new String[5]; // Bao sai
delete pd; //...
delete pj;
Thoâng baùo loãi cho ñoaïn chöông trình treân nhö sau:
delete pi;
Cannot find default constructor to initialize array element of type
'Diem'
Cannot find default constructor to initialize array element of type
String’
Loãi treân ñöôïc khaéc phuïc baèng caùch cung caáp phöông
thöùc thieát laäp ñeå ñoái töôïng coù khaû naêng töï khôûi ñoäng.
Caáp vaø huyû nhieàu ñoái töôïng Caáp vaø huyû nhieàu ñoái töôïng
class String Khi ñoù moïi phaàn töû ñöôïc caáp ñeàu ñöôïc khôûi ñoäng vôùi
{ cuøng giaù trò
char *p; int *pai = new int[10];
public: Diem *pad = new Diem[5];
String(char *s = "Alibaba") {p = strdup(s);} // ca 5 diem co cung toa do (0,0)
String(const String &s) {p = strdup(s.p);}
String *pas = new String[5];
~String() {delete [] p;}
// Ca 5 chuoi cung duoc khoi dong bang “Alibaba”
//...
}; Vieäc huyû nhieàu ñoái töôïng ñöôïc thöïc hieän baèng caùch duøng
class Diem delete vaø coù theâm daáu [] ôû tröôùc.
{ delete [] pas;
double x,y; delete [] pad;
public: delete [] pai;
Diem(double xx, double yy):x(xx),y(yy){};
Diem():x(0),y(0){}; (?) Coù theå thay ba phaùt bieåu treân baèng moät phaùt bieåu duy
//... nhaát sau ñöôïc khoâng ?
}; delete pas,pad,pai; // ??
Chöông 2. Lớp 107 Chöông 2. Lớp 108
2.4 Giao dieän vaø chi tieát caøi ñaët Lôùp ThoiDiem – Caùch 1
Lôùp coù hai phaàn taùch rôøi, moät laø phaàn giao dieän khai baùo class ThoiDiem
trong phaàn public ñeå ngöôøi söû duïng “thaáy” vaø söû duïng, vaø {
hai laø chi tieát caøi ñaët bao goàm döõ lieäu khai baùo trong int gio, phut, giay;
phaàn private cuûa lôùp vaø chi tieát maõ hoaù caùc haøm thaønh static bool HopLe(int g, int p, int gy);
phaàn, voâ hình ñoái vôùi ngöôøi duøng. public:
ThoiDiem(int g = 0, int p = 0, int gy = 0)
Ta coù theå thay ñoåi uyeån chuyeån chi tieát caøi ñaët, nghóa laø
{Set(g,p,gy);}
coù theå thay ñoåi toå chöùc döõ lieäu cuûa lôùp, cuõng nhö coù theå
void Set(int g, int p, int gy);
thay ñoåi chi tieát thöïc hieän caùc haøm thaønh phaàn (do söï
int LayGio() const {return gio;}
thay ñoåi toå chöùc döõ lieäu hoaëc ñeå caûi tieán giaûi thuaät).
int LayPhut() const {return phut;}
Nhöng neáu baûo ñaûm khoâng thay ñoåi phaàn giao dieän thì
int LayGiay() const {return giay;}
khoâng aûnh höôûng ñeán ngöôøi söû duïng, vaø do ñoù khoâng laøm
void Nhap();
ñoå vôõ kieán truùc cuûa heä thoáng.
void Xuat() const;
Lôùp ThoiDiem coù theå ñöôïc caøi ñaët vôùi caùc thaønh phaàn void Tang();
döõ lieäu laø giôø, phuùt, giaây hoaëc toång soá giaây tính töø 0 giôø. void Giam();
Chöông 2. Lớp 109 }; Chöông 2. Lớp 110
Lôùp ThoiDiem – Caùch 2 Giao dieän vaø chi tieát caøi ñaët
class ThoiDiem
{
Coù theå xem chi tieát ñaày ñuû lôùp thôøi ñieåm caøi ñaët baèng
long tsgiay;
giôø, phuùt, giaây vaø caøi ñaët baèng toång soá giaây trong taäp tin
static bool HopLe(int g, int p, int gy);
nguoàn thgian.cpp vaø thgian2.cpp,
public: Töông töï lôùp Stack coù theå ñöôïc caøi ñaët döôùi daïng maûng
ThoiDiem(int g = 0, int p = 0, int gy = 0) hoaëc döôùi daïng danh saùch lieân keát.
{Set(g,p,gy);}
void Set(int g, int p, int gy);
int LayGio() const {return tsgiay / 3600;}
int LayPhut() const {return (tsgiay%3600)/60;}
int LayGiay() const {return tsgiay % 60;}
void Nhap();
void Xuat() const;
void Tang();
void Giam();
}; Chöông 2. Lớp 111 Chöông 2. Lớp 112
2.5 Caùc nguyeân taéc xaây döïng lôùp Caùc nguyeân taéc xaây döïng lôùp
Khi ta coù theå nghó ñeán “noù” nhö moät khaùi nieäm rieâng reõ, Caùc thuoäc tính döõ lieäu phaûi vöøa ñuû ñeå moâ taû khaùi nieäm,
xaây döïng lôùp bieåu dieãn khaùi nieäm ñoù. Ví duï lôùp khoâng dö, khoâng thieáu.
SinhVien. Caùc thuoäc tính coù theå ñöôïc suy dieãn töø nhöõng thuoäc tính
Khi ta nghó ñeán “noù” nhö moät thöïc theå rieâng reõ, taïo ñoái khaùc thì duøng haøm thaønh phaàn ñeå thöïc hieän tính toaùn. Chu
töôïng thuoäc lôùp. Ví duï ñoái töôïng Sinh vieân “Nguyen Van vi, dieän tích tam giaùc laø thuoäc tính suy dieãn.
A” (vaø caùc thuoäc tính khaùc nhö maõ soá, naêm sinh…). // SAI // DUNG
class TamGiac class TamGiac
Lôùp laø bieåu dieãn cuï theå cuûa moät khaùi nieäm, vì vaäy lôùp
{ {
luoân luoân laø DANH TÖØ.
Diem A,B,C; Diem A,B,C;
Caùc thuoäc tính cuûa lôùp laø caùc thaønh phaàn döõ lieäu, neân
double ChuVi, public:
chuùng luoân luoân laø DANH TÖØ.
DienTich; //...
Caùc haøm thaønh phaàn laø caùc thao taùc chæ roõ hoaït ñoäng public: double ChuVi()const;
cuûa lôùp neân caùc haøm naøy laø ÑOÄNG TÖØ. //... double DienTich() const;
}; };
Caùc nguyeân taéc xaây döïng lôùp Caùc nguyeân taéc xaây döïng lôùp
Caù bieät coù theå coù moät soá thuoäc tính suy dieãn ñoøi hoûi Chi tieát caøi ñaët, bao goàm döõ lieäu vaø phaàn maõ hoaù caùc
nhieàu taøi nguyeân hoaëc thôøi gian ñeå thöïc hieän tính toaùn, ta
haøm thaønh phaàn coù theå thay ñoåi uyeån chuyeån nhöng
coù theå khai baùo laø döõ lieäu thaønh phaàn. Ví duï tuoåi trung phaàn giao dieän, nghóa laø phaàn khai baùo caùc haøm thaønh
bình cuûa daân Vieät Nam.
phaàn caàn phaûi coá ñònh ñeå khoâng aûnh höôûng ñeán ngöôøi
class QuocGia
{
söû duïng (xem phaàn 2.4). Tuy nhieân neân coá gaéng caøi ñaët
long DanSo; döõ lieäu moät caùch töï nhieân theo ñuùng khaùi nieäm.
double DienTich; // NEN // KHONG NEN
double TuoiTrungBinh; class PhanSo class PhanSo
//... { {
public:
double TinhTuoiTB() const;
int tu, mau; long tu_mau;
//... public: public:
}; //... //...
}; };
Chöông 2. Lớp 115 Chöông 2. Lớp 116
Caùc nguyeân taéc xaây döïng lôùp Caùc nguyeân taéc xaây döïng lôùp
Döõ lieäu thaønh phaàn neân ñöôïc keát hôïp thay vì phaân raõ Trong moïi tröôøng hôïp, neân coù phöông thöùc thieát laäp ñeå
// NEN // KHONG NEN khôûi ñoäng ñoái töôïng.
class TamGiac class TamGiac Neân coù phöông thöùc thieát laäp coù khaû naêng töï khôûi ñoäng
{ { khoâng caàn tham soá.
Diem A,B,C; double xA, yA, xB, yB,
xC, yC; Neáu ñoái töôïng coù nhu caàu caáp phaùt taøi nguyeân thì phaûi
public:
public: coù phöông thöùc thieát laäp, phöông thöùc thieát laäp baûn sao
//...
//... ñeå khôûi ñoäng ñoái töôïng baèng ñoái töôïng cuøng kieåu vaø coù
};
}; phöông thöùc huyû boû ñeå doïn deïp. Ngoaøi ra coøn phaûi coù
class HinhTron
class HinhTron pheùp gaùn (chöông tieáp theo).
{
Diem Tam; { Ngöôïc laïi, ñoái töôïng ñôn giaûn khoâng caàn taøi nguyeân
double BanKinh; double tx, ty, BanKinh; rieâng thì khoâng caàn phöông thöùc thieát laäp baûn sao vaø
public: public: cuõng khoâng caàn phöông thöùc huyû boû.
//... //...
}; };
Chöông 2. Lớp 117 Chöông 2. Lớp 118