Tác giả phạm hồng thái bài giảng ngôn ngữ LẬp trình c/C++



tải về 1.98 Mb.
trang43/55
Chuyển đổi dữ liệu07.07.2016
Kích1.98 Mb.
1   ...   39   40   41   42   43   44   45   46   ...   55

LỚP VÀ ĐỐI TƯỢNG


Trong lập trình hướng đối tượng, lớp (class) là một khái niệm rất quan trọng, nó cho phép giải quyết các vấn đề phức tạp của việc lập trình. Một lớp đơn (được định nghĩa như struct, union, hoặc class) bao gồm các hàm và dữ liệu có liên quan. Các hàm này là các hàm thành phần (member functon) hay còn là phương thức (method), thể hiện tác động của lớp có thể được thực hiện trên dữ liệu của chính lớp đó (data member).

Cũng giống như cấu trúc, lớp có thể xem như một kiểu dữ liệu. Vì vậy lớp còn gọi là kiểu đối tượng và lớp được dùng để khai báo các biến, mảng đối tượng (như thể dùng kiểu int để khai báo các biến mảng nguyên).

Như vậy từ một lớp có thể tạo ra (bằng cách khai báo) nhiều đối tượng (biến, mảng) khác nhau. Mỗi đối tượng có vùng nhớ riêng của mình và vì vậy ta cũng có thể quan niệm lớp chính là tập hợp các đối tượng cùng kiểu.

Khai báo lớp


Để khai báo một lớp, ta sử dụng từ khoá class như sau:

class tên_lớp

{

// Khai báo các thành phần dữ liệu (thuộc tính)

// Khai báo các phương thức (hàm)

};

Chú ý: Việc khai báo một lớp không chiếm giữ bộ nhớ, chỉcác đối tượng của lớp mới thực sự chiếm giữ bộ nhớ.

Thuộc tính của lớp có thể là các biến, mảng, con trỏ có kiểu chuẩn (int, float, char, char*, long,...) hoặc kiểu ngoài chuẩn đã định nghĩa trước (cấu trúc, hợp, lớp,...). Thuộc tính của lớp không thể có kiểu của chính lớp đó, nhưng có thể là con trỏ của lớp này, ví dụ:

class A


{

A x; //Không cho phép, vì x có kiểu lớp A

A* p ; //Cho phép , vì p là con trỏ kiểu lớp A

} ;

Khai báo các thành phần của lớp (thuộc tính và phương thức)

Các từ khóa private và public


Khi khai báo các thành phần dữ liệu và phương thức có thể dùng các từ khoá private và public để quy định phạm vi sử dụng của các thành phần này. Trong đó từ khóa private qui định các thành phần (được khai báo với từ khóa này) chỉ được sử dụng bên trong lớp (trong thân các phương thức của lớp). Các hàm bên ngoài lớp (không phải là phương thức của lớp) không được phép sử dụng các thành phần này. Đặc trưng này thể hiện tính che giấu thông tin trong nội bộ của lớp, để đến được các thông tin này cần phải thông qua chính các thành phần hàm của lớp đó. Do vậy thông tin có tính toàn vẹn cao và việc xử lý thông tin (dữ liệu) này mang tính thống nhất hơn và hầu như dữ liệu trong các lớp đều được khai báo với từ khóa này. Ngược lại với private, các thành phần được khai báo với từ khóa public được phép sử dụng ở cả bên trong và bên ngoài lớp, điều này cho phép trong chương trình có thể sử dụng các hàm này để truy nhập đến dữ liệu của lớp. Hiển nhiên nếu các thành phần dữ liệu đã khai báo là privte thì các thành phần hàm phải có ít nhất một vài hàm được khai báo dạng public để chương trình có thể truy cập được, nếu không toàn bộ lớp sẽ bị đóng kín và điều này không giúp gì cho chương trình. Do vậy cách khai báo lớp tương đối phổ biến là các thành phần dữ liệu được ở dạng private và thành phần hàm dưới dạng public. Nếu không quy định cụ thể (không dùng các từ khoá private và public) thì C++ hiểu đó là private.

Các thành phần dữ liệu (thuộc tính)


Được khai báo như khai báo các thành phần trong kiểu cấu trúc hay hợp. Bình thường các thành phần này được khai báo là private để bảo đảm tính giấu kín, bảo vệ an toàn dữ liệu của lớp không cho phép các hàm bên ngoài xâm nhập vào các dữ liệu này.

Các phương thức (hàm thành viên)


Thường khai báo là public để chúng có thể được gọi tới (sử dụng) từ các hàm khác trong chương trình.

Các phương thức có thể được khai báo và định nghĩa bên trong lớp hoặc chỉ khai báo bên trong còn định nghĩa cụ thể của phương thức có thể được viết bên ngoài. Thông thường, các phương thức ngắn được viết (định nghĩa) bên trong lớp, còn các phương thức dài thì viết bên ngoài lớp.

Một phương thức bất kỳ của một lớp, có thể sử dụng bất kỳ thành phần (thuộc tính và phương thức) nào của lớp đó và bất kỳ hàm nào khác trong chương trình (vì phạm vi sử dụng của hàm là toàn chương trình).

Giá trị trả về của phương thức có thể có kiểu bất kỳ (chuẩn và ngoài chuẩn)

Ví dụ sau sẽ minh hoạ các điều nói trên. Chúng ta sẽ định nghĩa lớp để mô tả và xử lý các điểm trên màn hình đồ hoạ. Lớp được đặt tên là DIEM.

Các thuộc tính của lớp gồm:

int x ; // Hoành độ (cột)

int y ; // Tung độ (hàng)

int m ; // Mầu

Các phương thức:

Nhập dữ liệu một điểm

Hiển thị một điểm

Ẩn một điểm

Lớp điểm được xây dựng như sau:

#include

#include

class DIEM

{

private:



int x, y, m ;

public:


void nhapsl() ;

void hien() ;

void an() { putpixel(x, y, getbkcolor());}

};
void DIEM::nhapsl()

{

cout <<"\n Nhap hoanh do (cot) va tung do (hang) cua diem: '';



cin >> x >> y ;

cout << ''\n Nhap ma mau cua diem: '';

cin >> m ;

}
void DIEM::hien()

{

int mau_ht ;



mau_ht = getcolor();

putpixel(x, y, m);

setcolor(mau_ht);

}

Qua ví dụ trên có thể rút ra một số chú ý sau:



Trong cả 3 phương thức (dù viết trong hay viết ngoài định nghĩa lớp) đều được phép truy nhập đến các thuộc tính x, y và m của lớp.

Các phương thức viết bên trong định nghĩa lớp (như phương thức an() ) được viết như một hàm thông thường.

Khi xây dựng các phương thức bên ngoài lớp, cần dùng thêm tên lớp và toán tử phạm vi :: đặt ngay trước tên phương phức để quy định rõ đây là phương thức của lớp nào.

Biến, mảng và con trỏ đối tượng


Như đã nói ở trên, một lớp (sau khi định nghĩa) có thể xem như một kiểu đối tượng và có thể dùng để khai báo các biến, mảng đối tượng. Cách khai báo biến, mảng đối tượng cũng giống như khai báo biến, mảng các kiểu khác (như int, float, cấu trúc, hợp,...), theo mẫu sau:

Tên_lớp danh sách đối ;

Tên_lớp danh sách mảng ;

Ví dụ sử dụng DIEM ở trên, ta có thể khai báo các biến, mảng DIEM như sau:

DIEM d1, d2, d3 ; // Khai báo 3 biến đối tượng d1, d2, d3

DIEM d[20] ; // Khai báo mảng đối tượng d gồm 20 phần tử

Mỗi đối tượng sau khi khai báo sẽ được cấp phát một vùng nhớ riêng để chứa các thuộc tính của nó. Chú ý rằng sẽ không có vùng nhớ riêng để chứa các phương thức cho mỗi đối tượng, các phương thức sẽ được sử dụng chung cho tất cả các đối tượng cùng lớp. Như vậy về bộ nhớ được cấp phát thì đối tượng giống cấu trúc.

Trong trường hợp này:

sizeof(d1) = sizeof(d2) = sizeof(d3) = 3*sizeof(int) = 6

sizeof(d) = 20*6 = 120


Thuộc tính của đối tượng


Trong ví dụ trên, mỗi đối tượng d1, d2, d3 và mỗi phần tử d[i] đều có 3 thuộc tính là x, y, m. Chú ý là mỗi thuộc tính đều thuộc về một đối tượng, vì vậy không thể viết tên thuộc tính một cách riêng rẽ mà bao giờ cũng phải có tên đối tượng đi kèm, giống như cách viết trong cấu trúc của C. Nói cách khác, cách viết thuộc tính của đối tượng như sau:

tên_đối_tượng.Tên_thuộc_tính

Với các đối tượng d1, d2, d3 và mảng d, có thể viết như sau:

d1.x; // Thuộc tính x của đối tượng d1

d2.x; // Thuộc tính x của đối tượng d2

d3.y; // Thuộc tính y của đối tượng d3

d[2].m; // Thuộc tính m của phần tử d[2]

d1.x = 100; // Gán 100 cho d1.x

d2.y =d1.x; // Gán d1.x cho d2.y


Sử dụng các phương thức


Cũng giống như hàm, một phương thức được sử dụng thông qua lời gọi. Tuy nhiên trong lời gọi phương thức bao giờ cũng phải có tên đối tượng để chỉ rõ phương thức thực hiện trên các thuộc tính của đối tượng nào.

Ví dụ lời gọi sau sẽ thực hiện nhập số liệu vào các thành phần d1.x, d1.y và d1.m: d1.nhapsl(); Câu lệnh sau sẽ thực hiện nhập số liệu vào các thành phần d[3].x, d[3].y và d[3].m: d[3].nhapsl() ;

Chúng ta sẽ minh họa các điều nói trên bằng một chương trình đơn giản sử dụng lớp DIEM để nhập 3 điểm, hiện rồi ẩn các điểm vừa nhập. Trong chương trình đưa vào hàm kd_do_hoa() dùng để khởi động hệ đồ hoạ.
#include

#include

#include
class DIEM

{

private:



int x, y, m ;

public:


void nhapsl();

void an() { putpixel(x,y,getbkcolor());}

void hien();

};
void DIEM::nhapsl()

{

cout << "\n Nhap hoanh do (cot) va tung do (hang) cua DIEM: '' ;



cin>> x >> y ;

cout << " \n Nhap ma tran cua diem: " ;

cin >> m ;

}
void DIEM::hien()

{

int mau_ht;



mau_ht = getcolor() ;

putpixel(x,y,m);

setcolor(mau_ht);

}
void kd_do_hoa()

{

int mh, mode ;



mh=mode=0;

initgraph(&mh, &mode, "C:\\TC\BGI");

}
void main()

{

DIEMd1, d2, d3 ;



d1.nhapsl(); d2.nhapsl(); d3.nhapsl();

kd_do_hoa();

setbkcolor(BLACK);

d1.hien(); d2.hien(); d3.hien();

getch();

d1.an(); d2.an(); d3.an();

getch();

closegraph();

}

Con trỏ đối tượng


Con trỏ đối tượng dùng để chứa địa chỉ của biến, mảng đối tượng. Nó được khai báo như sau:

Tên_lớp *con trỏ;

Ví dụ dùng lớp DIEM có thể khai báo:

DIEM *p1, *p2, *p3 ; // Khai báo 3 con trỏ p1, p2, p3

DIEM d1, d2 ; // Khai báo 2 đối tượng d1, d2

DIEM d[20] ; // Khai báo mảng đối tượng

và có thể thực hiện các câu lệnh:

p1= &d2 ; // p1 chứa địa chỉ của d2 , hay p1 trỏ tới d2

p2 = d ; // p2 trỏ tới đầu mảng d

p3 = new DIEM // Tạo một đt và chứa địa chỉ của nó vào p3

Để sử dụng thuộc tính của đối tượng thông qua con trỏ, ta viết như sau:

Tên_con_trỏ ® Tên_thuộc_tính

Chú ý: Nếu con trỏ chứa địa chỉ đầu của mảng, có thể dùng con trỏ như tên mảng.

Như vậy sau khi thực hiện các câu lệnh trên thì:

p1 ® x và d2.x là như nhau

p2[i].y và d[i].y là như nhau

Từ đó ta có quy tắc sử dụng thuộc tính: Để sử dụng một thuộc tính của đối tượng ta phải dùng phép . hoặc phép ®. Trong chương trình, không cho phép viết tên thuộc tính một cách đơn độc mà phải đi kèm tên đối tượng hoặc tên con trỏ theo các mẫu sau:

Tên_đối_tượng.Tên_thuộc_tính

Tên_con_trỏ ® Tên_thuộc_tính

Tên_mảng_đối_ tượng[chỉ_số].Tên_thuộc_tính

Tên_con_trỏ[chỉ_số].Tên_thuộc_tính

Chương trình dưới đây cũng sử dụng lớp DIEM để nhập một dãy điểm, hiển thị và ẩn các điểm vừa nhập. Chương trình dùng một con trỏ kiểu DIEM và dùng toán tử new để tạo ta một dãy đối tượng

#include

#include

#include

class DIEM

{

private:



int x, y, m ;

public:


void nhapsl();

void an() { putpixel(x,y,getbkcolor());}

void hien();

};
void DIEM::nhapsl()

{

cout <<"\n Nhap hoanh do (cot) va tung do (hang) cua diem:'' ;



cin >> x >> y ;

cout << " \n Nhap ma mau cua DIEM: '' ;

cin >> m ;

}
void DIEM::hien()

{

int mau_ht;



mau_ht = getcolor() ;

putpixel(x,y,m);

setcolor(mau_ht);

}
void kd_do_hoa()

{

int mh, mode ;



mh=mode=0;

initgraph(&mh, &mode, ''C:\\TC\BGI'');

}
void main()

{

DIEM *p;



int i, n;

cout << ''So diem: '' ;

cin >> n;

p = new DIEM[n+1];

for (i=1;i<=n;++i)

p[i].nhapsl();

kd_do_hoa();

for (i=1;i<=n;++i) p[i].hien();

getch();

for (i=1;i<=n;++i) p[i].an();

getch();

closegraph();

}

1   ...   39   40   41   42   43   44   45   46   ...   55


Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2016
được sử dụng cho việc quản lý

    Quê hương