Chương 7. Lớp và đối tượng
int xmax, ymax;
class HT
{
private:
int r, m ;
int xhien, yhien;
char *pht;
int hienmh;
public:
HT();
HT(int n, int m1 = 15);
~HT();
void hien(int x, int y);
void an();
};
HT:: HT()
{
r = m = hienmh = 0;
xhien = yhien = 0;
pht = NULL;
}
HT::HT(int n, int m1)
{
r = n; m = m1; hienmh = 0;
xhien = yhien = 0;
if (r<0) r = 0;
if (r = = 0) pht = NULL;
else
{
int size; char *pmh;
size = imagesize(0, 0, r+r, r+r);
pmh = new char[size];
249
Chương 7. Lớp và đối tượng
getimage(0, 0, r+r, r+r, pmh);
setcolor(m);
circle(r, r, r );
setfillstyle(1, m);
floodfill(r, r, m);
pht = new char[size];
getimage(0, 0, r+r, r+r, pht);
putimage(0, 0, pmh, COPY_PUT);
delete pmh;
pmh = NULL;
}
}
void HT::hien(int x, int y)
{
if (pmh! = NULL && !hienmh) // Chua hien
{
hienmh = 1;
xhien = x; yhien = y;
putimage(x, y, pht, XOR_PUT);
}
}
void HT::an()
{
if (hienmh) // Dang hien
{
hienmh = 0;
putimage(xhien, yhien, pht, XOR_PUT);
}
}
HT::~HT()
{
an();
250
Chương 7. Lớp và đối tượng
if (pht! = NULL)
{
delete pht;
pht = NULL;
}
}
void ktdh()
{
int mh = 0, mode = 0;
initgraph(&mh, &mode, " ");
xmax = getmaxx();
ymax = getmaxy();
}
void ve_bau_troi()
{
for (int i = 0; i<2000; ++i)
putpixel(random(xmax), random(ymax), 1+random( 15));
}
void ht_di_dong_xuong()
{
HT h(50, 4);
HT u(60, 15);
h.hien(0, 0);
u.hien(40, 0);
for (int x = 0; x< = 340; x+ = 10)
{
h.an();
u.an();
h.hien(x, x);
delay(200);
u.hien(x+40, x);
delay(200);
251
Chương 7. Lớp và đối tượng
}
}
void ht_di_dong_len()
{
HT h(50, 4);
HT u(60, 15);
h.hien(340, 340);
u.hien(380, 340);
for (int x = 340; x> = 0; x- = 10)
{
h.an();
u.an();
u.hien(x, x);
delay(200);
u.hien(x+40, x);
delay(200);
}
};
void main()
{
ktdh();
ve_bau_troi();
ht_di_dong_xuong();
ht_di_dong_len();
getch();
closegraph();
}
Các nhận xét:
+ Trong thân hàm hủy gọi tới phương thức an().
+ Điều gì xẩy ra khi bỏ đi hàm hủy:
• Khi gọi hàm ht_di_dong_xuong() thì có 2 đối tượng kiểu HT được tạo ra.
Trong thân hàm sử dụng các đối tượng này để vẽ các hình tròn di
252
Chương 7. Lớp và đối tượng
chuyển xuống. Khi thoát khỏi hàm thì 2 đối tượng (tạo ra ở trên) được
giải phóng. Vùng nhớ của các thuộc tính của chúng bị thu hồi, nhưng
vùng nhớ cấp phát cho thuộc tính pht chưa được giải phóng và ảnh của
2 hình tròn (ở phía dưới màn hình) vẫn không được cất đi.
• Điều tương tự xẩy ra sau khi ra khỏi hàm ht_di_dong_len(): vùng nhớ
cấp phát cho thuộc tính pht chưa được giải phóng và ảnh của 2 hình
tròn (ở phía trên màn hình) vẫn không được thu dọn.
VI. CÁC HÀM TRỰC TUYẾN (INLINE)
Một số mở rộng của C++ đối với C đã được trình bày trong các chương trước
như biến tham chiếu, định nghĩa chồng hàm, hàm với đối mặc định … Phần này ta
xem một đặc trưng khác của C++ được gọi là hàm trực tuyến (inline).
1. Ưu nhược điểm của hàm
Việc tổ chức chương trình thành các hàm có 2 ưu điểm rõ rệt:
Thứ nhất là chia chương trình thành các đơn vị độc lập, làm cho chương trình
được tổ chức một cách khoa học dễ kiểm soát, dễ phát hiện lỗi, dễ phát triển và mở
rộng.
Thứ hai là giảm được kích thước chương trình, vì mỗi đoạn chương trình thực
hiện nhiệm vụ của hàm được thay bằng một lời gọi hàm.
Tuy nhiên hàm cũng có nhược điểm là làm chậm tốc độ chương trình do phải
thực hiện một số thao tác có tính thủ tục mỗi khi gọi hàm như: cấp phát vùng nhớ
cho các đốivà biến cục bộ, truyền dữ liệu của các tham số cho các đối, giải phóng
vùng nhớ trước khi thoát khỏi hàm.
Các hàm trực tuyến trong C++ có khả năng khắc phục được các nhược điểm
nói trên.
2. Các hàm trực tuyến
Để biến một hàm thành trực tuyến ta viết thêm từ khoá inline vào trước khai
báo nguyên mẫu hàm. Nếu không dùng nguyên mẫu thì viết từ khoá này trước dòng
đầu tiên của định nghĩa hàm.
Ví dụ 1
:
inline float f(int n, float x);
float f(int n, float x)
{
// Các câu lệnh trong thân hàm
}
253