Bài giảng kỹ thuật lập trình_Chương 6: Lớp và đối tượng II - Pdf 17

© 2004, HOÀNG MINH SƠN
Chương 1
0101010101010101100001
0101010101010101100001
0101010101010101100001
0101010100101010100101
0101010100101010100101
0101010100101010100101
1010011000110010010010
1010011000110010010010
1010011000110010010010
1100101100100010000010
1100101100100010000010
1100101100100010000010
0101010101010101100001
0101010101010101100001
0101010101010101100001
0101010100101010100101
0101010100101010100101
0101010100101010100101
1010011000110010010010
1010011000110010010010
1010011000110010010010
1100101100100010000010
1100101100100010000010
1100101100100010000010
0101010101010101100001
0101010101010101100001
0101010101010101100001
0101010100101010100101
0101010100101010100101

Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Có bao nhiêu cách ₫ể tạo/hủy ₫ối tượng?
 Tạo/hủy tự ₫ộng: Định nghĩa một biến thuộc một lớp
—Bộ nhớ của ₫ối tượng (chứa các dữ liệu biến thành viên) ₫ược tự
₫ộng cấp phát giống như với một biến thông thương
—Bộ nhớ của ₫ối tượng ₫ược giải phóng khi ra khỏi phạm vi ₫ịnh
nghĩa
class X {
int a, b;

};
void f( X x1) {
if ( ) {
X x2;

}
}
X x;
6.1 Tạovàhủy ₫ốitượng
Đốitượng ₫ượctạo ra trong ngănxếp
Đốitượng ₫ượctạo ra trong vùng dữ liệuchương trình
Thời ₫iểmbộ nhớ cho x2 ₫ượcgiải phóng
Thời ₫iểmbộ nhớ cho x1 ₫ượcgiải phóng
4
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
 Tạo/hủy ₫ối tượng ₫ộng bằng toán tử new và delete:
X* pX = 0;

ban ₫ầutheoý muốncủachương trình?
X x = {1, 2}; // Error! cannot access private members
 Làm sao ₫ể tạomột ₫ốitượng là bảnsaocủamột ₫ốitượng có
kiểu khác?
class Y { int c, d; };
Y y = x; // Error, X and Y are not the same type,
// they are not compatible
6
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Vấn ₫ề 2: Quảnlýtàinguyên
 Đốivớicác₫ốitượng sử dụng bộ nhớ₫ộng, việccấpphátvàgiải
phóng bộ nhớ₫ộng nên thựchiệnnhư thế nào cho an toàn?
class Vector {
int nelem;
double *data;
public:
void create(int n) { data = new double[nelem=n];}
void destroy() { delete[] data; nlem = 0; }
void putElem(int i, double d) { data[i] = d; }
};
Vector v1, v2;
v1.create(5);
// forget to call create for v2
v2.putElem(1,2.5); // BIG problem!
// forget to call destroy for v1, also a BIG problem
 Vấn ₫ề tương tự xảyrakhisử dụng tệptin, cổng truyềnthông,
và các tài nguyên khác trong máy tính
7

8
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
 Hàm tạolàcơ hội ₫ể khởitạovàcấp phát tài nguyên
 Hàm hủylàcơ hội ₫ể giải phóng tài nguyên ₫ãcấpphát
 Mộtlớpcóthể có nhiềuhàmtạo (khác nhau ở số lượng các
tham số hoặckiểu các tham số)
 Mặc ₫ịnh, compiler tự₫ộng sinh ra mộthàmtạo không
tham số và mộthàmtạobảnsao
— Thông thường, mã thực thi hàm tạomặc ₫ịnh do compiler sinh
ra là rỗng
— Thông thường, mã thực thi hàm tạobản sao do compiler sinh
ra sao chép dữ liệucủa ₫ốitượng theo từng bit
—Khixâydựng mộtlớp, nếucầncóthể bổ sung các hàm tạomặc
₫ịnh, hàm tạobảnsaovàcáchàmtạokháctheoý muốn
 Mỗilớpcóchínhxácmộthàmhủy, nếuhàmhủy không
₫ược ₫ịnh nghĩathìcompiler sẽ tự sinh ra mộthàmhủy:
— Thông thường, mã hàm hủy do compiler tạoralàrỗng
—Khicầncóthể₫ịnh nghĩahàmhủy ₫ể thực thi mã theo ý muốn
6.2 Xây dựng các hàm tạovàhàmhủy
9
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Ví dụ: LớpTime cảitiến
class Time {
int hour, min, sec;
public:
Time() : hour(0), min(0), sec(0) {}

Vector v1; // v1 has 0 elements
Vector v2(5,0); // v2 has 5 elements init. with 0
Vector v3=v2; // v3 is a copy of v2
Vector v4(v3); // the same as above
Vector f(Vector b) {
double a[] = {1, 2, 3, 4};
Vector v(4, a);

return v;
}
// Do not care about memory management
11
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Phiên bảnthứ nhất
class Vector {
int nelem;
double* data;
public:
Vector() : nelem(0), data(0) {}
Vector(int n, double d =0.0);
Vector(int n, double *array);
Vector(const Vector&);
~Vector();
int size() const { return nelem; }
double getElem(int i) const { return data[i];}
void putElem(int i, double d) { data[i] = d; }
private:
void create(int n) { data = new double[nelem=n]; }

 Hàm tạobảnsao₫ượcgọi khi sao chép ₫ốitượng:
— Khi khai báo các biến x2-x4 như sau:
X x1;
X x2(x1);
X x3 = x1;
X x4 = X(x1);
— Khi truyềnthamsố qua giá trị cho mộthàm, hoặckhimộthàmtrả
về một ₫ốitượng
void f(X x) { }
X g( ) {
X x1;
f(x1);

return x1;
}
14
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Cú pháp chuẩnchohàm tạobảnsao?
class X {
int a, b;
public:
X() : a(0), b(0) {}
X(X x); // (1)
X(const X x); // (2)
X(X& x); // (3)
X(const X& x); // (4)

};

Vector::Vector(const Vector& a) {
create(a.nelem);
for (int i=0; i < nelem; ++i)
data[i] = a.data[i];
}
0 0 0 0 0
a.nelem : 5
a.data
b.nelem : 5
b.data
16
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Mộtsố₫iểmcầnlưuý
 Nhiềuhàmtạonhưng chỉ có mộthàmhủy=> hàmhủyphải
nhấtquánvớitấtcả hàm tạo
—Trongvídụ lớp Vector, có hàm tạocấpphátbộ nhớ, nhưng hàm tạo
mặc ₫ịnh thì không => hàm hủycầnphânbiệtrõcáctrường hợp
 Khi nào hàm tạocócấp phát chiếmdụng tài nguyên thì cũng
cần ₫ịnh nghĩalạihàmhủy
 Trong mộtlớpmàcó₫ịnh nghĩahàmhủythìgầnnhư chắcchắn
cũng phải ₫ịnh nghĩahàmtạobảnsao(nếunhư cho phép sao
chép)
 Mộtlớpcóthể cấmsaochépbằng cách khai báo hàm tạobản
sao trong phần private, ví dụ:
class Y { int a, b; Y(const&);
};
void main() { Y y1;
Y y2=y1; // error!

double re, im;
public:
Complex(double r = 0, double i =0): re(r),im(i) {}
double real() const { return re; }
double imag() const { return im; }
Complex operator+(const Complex& b) const {
Complex z(re+b.re, im+b.im);
return z;
}
Complex operator-(const Complex& b) const {
return Complex(re-b.re,im-b.im);
}
Complex operator*(const Complex&) const;
Complex operator/(const Complex&) const;
Complex& operator +=(const Complex&);
Complex& operator -=(const Complex&);

};
19
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
#include “mycomplex.h”
Complex Complex::operator*(const Complex& b) const {
// left for exercise!
}
Complex Complex::operator/(const Complex& b) const {
// left for exercise!
}
Complex& Complex::operator +=(const Complex& b) {

21
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Mộtsố qui ₫ịnh
 Có thể thay ₫ổingữ nghĩacủamộttoántử cho các kiểumới,
nhưng không thay ₫ổi ₫ượccúpháp(vídụ số ngôi, trình tựưu
tiên thựchiện, )
 Trong mộtphéptoán₫ịnh nghĩalại, phảicóítnhấtmộttoán
hạng có kiểumới (struct, union hoặc class) => không ₫ịnh nghĩa
l
ạichocáckiểudữ liệucơ bảnvàkiểudẫnxuấttrựctiếp ₫ược!
—Vídụ không thể₫ịnh nghĩalạitoántử ^ là phép tính lũythừacho
các kiểusố họccơ bản (int, float, double, )
 Chỉ nạpchồng ₫ược các toán tử có sẵn, không ₫ưathêm₫ược
các toán tử mới
—Vídụ không thể bổ sung ký hiệutoántử ** cho phép toán lũythừa
 Nạpchồng toán tử thựcchấtlànạpchồng tên hàm => cầnlưuý
các qui ₫ịnh về nạpchồng tên hàm
 Đasố hàm toán tử có thể nạpchồng hoặc dướidạng hàm
thành viên, hoặc dướidạng hàm phi thành viên
 Mộtsố toán tử chỉ có thể nạpchồng bằng hàm thành viên
 Mộtsố toán tử chỉ nên nạpchồng bằng hàm phi thành viên
22
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Nạpchồng toán tử []
 Yêu cầu: truy nhập các phầntử củamột ₫ốitượng thuộclớp
Vector vớitoántử [] giống như₫ốivớimộtmảng

data = b.data
return *this;
}
24
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
 Vấn ₫ề tương tự như hàm tạobảnsaomặc ₫ịnh, thậmchícòn
tồitệ hơn

{
Vector a(5), b(3), c;
b = a;
c = a;
} // calling destructor for a, b and c causes
// 3 times calling of delete[] operator for the
// same memory space
0 0 0 0 0
a.nelem : 5
a.data
b.nelem : 5
b.data
0 0 0
c.nelem : 5
c.data
25
© 2004, HOÀNG MINH SƠN
Chương 6: Lớpvàđốitượng II
© 2005 - HMS
Nạpchồng toán tử gán cho lớp Vector


Nhờ tải bản gốc
Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status