1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng Ngôn ngữ lập trình C và C++: Bài 6 - TS. Đỗ Đăng Khoa

63 10 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 63
Dung lượng 264,9 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bài 6 trình bày về Cấu trúc và Lớp. Nội dung cụ thể của chương này gồm có: Khái niệm về Cấu trúc (Struct), khai báo cấu trúc, khai báo biến kiểu cấu trúc, khởi tạo biến cấu trúc, truy cập đến thành phần của cấu trúc,...

Trang 1

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

Trang 2

Khái niệm về Cấu trúc (Struct)

Một tập hợp của một hoặc nhiều biến, có thể khác kiểu nhau,

được nhóm lại dưới một tên duy nhất cho tiện xử lý

Trong các ứng dụng về cơ sở dữ liệu, kiểu cấu trúc còn được

gọi là bản ghi

Việc định nghĩa cấu trúc sẽ tạo ra kiểu dữ liệu mới

Ví dụ:

Ví dụ:

Hồ sơ nhân viên: mỗi nhân viên được mô tả bởi một tập các

thuộc tính như: tên, địa chỉ, số CMT, lươngM Một trong số các

thuộc tính này lại có thể là một cấu trúc: tên có thể có vài thành

phần (họ, tên đệm, tên), địa chỉ và lương cũng có thể như vậy

Tài khoản ngân hàng: tên chủ tài khoản, tên tài khoản, số dư

tài khoản, loại tiền

Trang 3

Khai báo cấu trúc

Khai báo một cấu trúc

struct <tên kiểu>

Trang 4

Khai báo cấu trúc

Mỗi thành phần giống như một biến riêng của kiểu, nó gồm

kiểu và tên thành phần Một thành phần cũng còn được gọi là

trường

Phần tên của kiểu cấu trúc và phần danh sách biến cấu trúc có

thể có hoặc không Tuy nhiên trong khai báo kí tự kết thúc cuối

cùng phải là dấu chấm phẩy (;)

cùng phải là dấu chấm phẩy (;)

Các kiểu cấu trúc được phép khai báo lồng nhau, nghĩa là một

thành phần của kiểu cấu trúc có thể lại là một trường có kiểu cấu

trúc

Một biến có kiểu cấu trúc sẽ được phân bố bộ nhớ sao cho các

thực hiện của nó được sắp liên tục theo thứ tự xuất hiện trong

khai báo

Trang 5

Khai báo biến kiểu cấu trúc

Khai báo ngay sau dấu ngoặc }, danh sách các biến;

struct { } x, y, z;

Khai báo như biến thông thường (trong C)

struct <tên cấu trúc> <danh sách biến>

Khai báo như biến thông thường (trong C++)

<tên cấu trúc> <danh sách biến>;

Trang 6

Khởi tạo biến cấu trúc

Khởi tạo ngay định nghĩa của nó với danh sách các khởi tạo

Trang 7

Truy cập đến thành phần của cấu trúc

Biến không phải con trỏ

tên_cấu_ trúc.thành_phần

Biến con trỏ:

tên_cấu_ trúc->thành_phần,(*tên_cấu_trúc).thành_phần

Trang 8

Nếu khai báo screen là

Nếu khai báo screen là

rect screen;

thì

screen.pt1.xchỉ đến tọa độ x của thành phần pt1 của screen

Trang 9

Hàm và Cấu trúc

Các thao tác hợp lệ duy nhất với một cấu trúc là

 Sao chép nó hoặc gán cho nó,

 Lấy địa chỉ qua &,

Truy xuất các thành phần của nó

Việc sao chép và gán bao gồm

Việc sao chép và gán bao gồm

 Truyền đối số tới hàm

Trả giá trị từ hàm

Trang 10

struct Sophuc// Khai báo kiểu số phức dùng chung

struct Sophuc// Khai báo kiểu số phức dùng chung

{

float thuc;

float ao;

};

Trang 11

Hàm và Cấu trúc

Sophuc Cong(Sophuc x, Sophuc y)

{

Sophuc kq;

kq.thuc = x.thuc + y.thuc ;

kq.ao = x.ao + y.ao ;

Trang 12

Hàm và Cấu trúc

void main(){

Sophuc x, y;

cout << "x = " ; cin >> x.thuc >> x.ao ;

cout << "y = " ; cin >> y.thuc >> y.ao ;

cout << "x + y = " ; In(Cong(x,y)) ;}

Ví dụ hàm trả về con trỏ cấu trúc

Ví dụ hàm trả về con trỏ cấu trúc

Sophuc* Tru(Sophuc x, Sophuc y){

Sophuc* kq=new Sophuc;

kq->thuc = x.thuc + y.thuc ;

kq->ao = x.ao + y.ao ;

return kq;

}

Trang 13

Hàm và Cấu trúc

Hàm có đối số là cấu trúc

Là một biến cấu trúc

Là một con trỏ cấu trúc

Là một tham chiếu cấu trúc

Là một mảng cấu trúc hình thức hoặc con trỏ mảng

Trường hợp cấu trúc lớn, sử dụng con trỏ và tham chiếu sẽ hiệu

quả hơn việc phải sao chép cả cấu trúc

Con trỏ cấu trúc tương tương tự như con trỏ tới các biến thông

thường

Trang 16

Kiểu Hợp

Kiểu hợp cũng có nhiều thành phần giống kiểu cấu trúc

Tuy nhiên, các thành phần của chúng sử dụng chung nhau một

vùng nhớ

Kích thước của một kiểu hợp là độ dài của trường lớn nhất và

việc

Thay đổi giá trị một thành phần sẽ ảnh hưởng đến tất cả các

Thay đổi giá trị một thành phần sẽ ảnh hưởng đến tất cả các

Trang 18

Từ Khóa typedef

Một kiểu dữ liệu có thể được định nghĩa bằng cách sử

dụng từ khóa typedef

Nó không tạo ra một kiểu dữ liệu mới, mà định nghĩa

một tên mới cho một kiểu đã có

một tên mới cho một kiểu đã có

Cú pháp: typedef type tên;

Ví dụ: typedef float deci;

Trang 19

Lập trình hướng đối tượng

Đối tượng: là một đơn vị đầy đủ được kết hợp bởi các

dữ liệu và chỉ thị

Đối tượng được chia thành hai thành phần: các

phương thức (hàm) và các thuộc tính (biến)

Phương thức: là phương tiện để sử dụng đối tượng,

Phương thức: là phương tiện để sử dụng đối tượng,

trong khi các thuộc tính sẽ mô tả đối tượng có tính chất

Đối tượng được trừu tượng hóa qua việc định nghĩa

của các lớp

Trang 20

Các đặc tính của lập trình hướng đối tượng

Tính trừu tượng (abstraction):

Bỏ qua một số khía cạnh thông tin, chỉ tập trung vào những

cốt lõi cần thiết

Mỗi đối tượng có thể hoàn tất các công việc một cách nội

bộ, báo cáo, thay đổi trạng thái của nó và liên lạc với các đối

tượng khác, không cần cho biết làm cách nào tiến hành

tượng khác, không cần cho biết làm cách nào tiến hành

được các thao tác (trừu tượng dự liệu)

Tính trừu tượng còn thể hiện qua việc một đối tượng ban

đầu có thể có một số đặc điểm chung cho nhiều đối tượng

khác như là sự mở rộng của nó nhưng bản thân đối tượng

này có thể không có các biện pháp thi hành (lớp trừu tượng

hay lớp cơ sở)

Trang 21

Các đặc tính của lập trình hướng đối tượng

Tính đóng gói (encapsulation) và che giấu thông tin

(information hiding):

Tính chất này không cho phép người sử dụng các đối tượng

thay đổi trạng thái nội tại của một đối tượng

Chỉ có các phương thức nội tại của đối tượng cho phép thay

đổi trạng thái của nó

đổi trạng thái của nó

Tính đa hình (polymorphism):

Thông qua việc gửi các thông điệp (message)

Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo

đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng

khác nhau

Trang 22

Các đặc tính của lập trình hướng đối tượng

Tính kế thừa (inheritance):

Cho phép một đối tượng có thể có sẵn các đặc tính mà đối

tượng khác đã có thông qua kế thừa

Cho phép các đối tượng chia sẻ hay mở rộng các đặc tính

sẵn có mà không phải tiến hành định nghĩa lại

sẵn có mà không phải tiến hành định nghĩa lại

Không phải ngôn ngữ hướng đối tượng nào cũng có tính

chất này

Trang 23

Khái niệm về lớp (Class)

Một lớp 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

function) hay còn là phương thức (method)

Giống như cấu trúc, lớp có thể xem như một kiểu dữ

liệu

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

Trang 24

Khai báo lớp (Class)

Trang 25

Khai báo lớp (Class)

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, )

kiểu chuẩn (int, float, char, char*, long, )

Thuộc tính của lớp có thể là kiểu ngoài chuẩn đã định

nghĩa trước (struct, union, class, )

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

Trang 26

Khai báo lớp (Class)- Các đặc tả truy cập

Các đặc tả truy cập này thay đổi các quyền truy cập

mà các thành phần khai báo sau chúng có được:

private: chỉ có thể truy cập từ bên trong thành phần

cùng lớp đó (trong thân các phương thức của lớp)

hoặc từ các thành phần bạn (friend) của nó

hoặc từ các thành phần bạn (friend) của nó

protected: như private, ngoài ra còn từ các thành

phần của các lớp dẫn xuất (lớp con) của lớp đó

public: có thể truy cập từ mọi nơi mà đối tượng hiển

thị

Mặc định của class là quyền truy cập private đối với

tất cả thành phần của nó

Trang 27

Khai báo lớp (Class)- Các đặc tả truy cập

Nếu các thành phần dữ liệu đã khai báo là private thì

các hàm thành phần phải có ít nhất một vài hàm được

khai báo dạng public để 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

chương trình

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à hàm thành phần

dưới dạng public

Trang 28

Khai báo lớp (Class)- Dữ liệu thành phần

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 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

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

Không được khai báo là auto, register hoặc extern

Kiểu: enum, kiểu dữ liệu có sẵn (chuẩn) hoặc người

dùng định nghĩa (struct, union, class)

Trang 29

Khai báo lớp (Class)- Hàm thành phần

Hàm thành phần dùng để truy cập có kiểm soát vào thành

Trang 30

Định nghĩa lớp (Class)- Hàm thành phần

Định nghĩa hàm: có thể được triển khai luôn trong thân lớp

hoặc bên ngoài lớp cùng toán tử phạm vi ::

(kiểu_trả_về tên_lớp::tên_hàm(…))

Hàm được định nghĩa bên trong lớp sẽ được tự động coi

là hàm thành phần inline bởi trình biên dịch

Hàm thành phần được phép truy xuất tới các dữ liệu thành

phần, kể cả dữ liệu kiểu private

Trang 31

void displaypoint() ; //Hiện một ñiểm

//Ẩn một ñiểm, hàm ñịnh nghĩa trong khai báo

void hidepoint() { putpixel(x, y,getbkcolor());

} };

Trang 33

Các hàm thành phần của lớp có quyền truy cập không

hạn chế vào thành phần dữ liệu của lớp đó

Việc truy cập vào các thành phần dữ liệu và hàm từ

ngoài phạm vi lớp do người lập trình kiểm soát

Trang 34

Đối tượng, Mảng và con trỏ đối tượng của

lớp

Một đối tượng (object) là một thể nghiệm của lớp  Lớp

là một định nghĩa của đối tượng

Chú ý: Lớp là một kiểu dữ liệu, đối tượng của lớp này chỉ

là một biến

Ví dụ:

point a;

point a;

Cách khai báo mảng đối tượng, con trỏ đối tượng cũng

giống như khai báo biến, mảng các kiểu khác (như int,

float, struct, union, )

Ví dụ:

point b[10], *c;

c= new point;

Trang 35

Truy xuất thuộc tính của đối tượng

Mỗi thuộc tính đều thuộc về một đối tượng, 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

a.x;// chỉ dùng ñược trong hàm thành phần

b=&a; b->y; // chỉ dùng ñược trong hàm thành phần

Chỉ có thể truy xuất thuộc tính private của đối tượng bằng các

hàm thành phần

Trang 36

Sử dụng hàm thành phần của đối tượng

Cũng giống như hàm thông thường, hàm thành phần được

sử dụng thông qua lời gọi

 Tuy nhiên trong lời gọi hàm thành phần bao giờ cũng phải có

tên đối tượng để chỉ rõ hàm thực hiện trên các thuộc tính của

đối tượng nào

Trang 37

Đối của hàm thành phần, con trỏ this

Con trỏ this là con trỏ tới chính đối tượng của nó

Con trỏ this là đối thứ nhất của hàm thành phần

Các thuộc tính viết trong hàm inputdata() gọi bởi một đối

tượng được hiểu là thuộc chính đối tượng đó do con trỏ this trỏ

tới

Cách viết tường minh lại hàm inputdata()

Cách viết tường minh lại hàm inputdata()

void point::inputdata(){

cout <<"\n Nhap hoanh do va tung do cua diem:”;

cin >> this->x >>this-> y ;

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

cin >> this->m ;

}

Trang 38

Đối của hàm thành phần, con trỏ this

Tham số truyền cho đối con trỏ this chính là địa chỉ của đối

tượng đi kèm với phương thức trong lời gọi phương thức

Ví dụ:

point a;

a.inputdata()

Trong trường hợp này tham số truyền cho con trỏ this chính

Trong trường hợp này tham số truyền cho con trỏ this chính

là địa chỉ của a:

this = &a

Con trỏ this còn được dùng trong các hàm thành phần cần trả

lại chính đối tượng có phương thức đang triển khai

Trang 39

Đối tượng hằng và các hàm thành phần hằng

Đối tượng hằng là đối tượng được khai báo với từ khoá cons

Mọi ý định sửa đổi các đối tượng hằng đều bị chương trình

báo lỗi khi biên dịch

Các hàm thành phần "không sủa đổi dữ liệu của lớp", tức là

các hàm thành phần hằng và là các hàm được khai báo với từ

khoá const, mới được phép thực hiện trên các đối tượng hằng

khoá const, mới được phép thực hiện trên các đối tượng hằng

Khi viết các hàm thành phần của lớp, cần xác định ngay hàm

nào cần sửa hàm nào không cần sửa đổi dữ liệu của lớp và đặt

thêm từ khoá const tương ứng trong khai báo và định nghĩa

hàm

Trang 41

Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử

Các đối tượng cần được khởi tạo dữ liệu thành phần hoặc

gán bộ nhớ động trong quá trình sinh ra để tránh việc trả lại các

giá trị không mong muốn trong quá trình thao tác chúng

Hàm dựng cũng là một hàm thành phần của lớp (nhưng là

hàm đặc biệt) được tự động gọi bất cứ khi nào một đối tượng

mới của lớp này được tạo ra

mới của lớp này được tạo ra

Chương trình dịch sẽ cấp phát bộ nhớ cho đối tượng sau đó

sẽ gọi đến hàm dựng

Hàm dựng sẽ khởi gán giá trị cho các thuộc tính của đối

tượng và có thể thực hiện một số công việc khác nhằm chuẩn

bị cho đối tượng mới

Trang 42

Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử

Hàm dựng phải có tên giống tên lớp, không có giá trị trả về

(kể cả void)

Nếu không định nghĩa hàm dựng của một lớp, trình biên dịch

sẽ sinh ra hàm dựng ngầm định

 Hàm dựng ngầm định không có đối và chỉ đơn thuần đặt

không vào mọi byte của biến thể nghiệm của một đối tượng

Một lớp có thể có nhiều hơn một hàm dựng (cùng tên, khác

bộ đối số)

Trang 43

Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử

point()// hàm dựng không ñối

point()// hàm dựng không ñối

{x=0; y=0; m=1;}

//hàm dựng có ñối

point(int x1, int y1, int m1);

};

Trang 44

Định nghĩa lớp- Hàm dựng (tạo)/ Cấu tử

point :: point(int x1, int y1, int m1)

{x = x1; y = y1; m = m1; }

Ví dụ:

point a; // Gọi tới hàm dựng không ñối

// Kết quả a.x = 0, a.y = 0, a.m = 1

point b(300, 100, 5);// Gọi tới hàm dựng có ñối

point b(300, 100, 5);// Gọi tới hàm dựng có ñối

// Kết quả b.x = 300, b.y = 100, b.m = 5

point c[5] ;// Gọi tới hàm dựng không ñối 5 lần

 Các hàm có đối kiểu lớp, thì đối chỉ xem là các tham số hình

thức, vì vậy khai báo đối (trong dòng đầu của hàm) sẽ không

tạo ra đối tượng mới và do đó không gọi tới các hàm dựng

Trang 45

point::point(const point& source)

point::point(const point& source)

Trang 46

Định nghĩa lớp- Hàm dựng sao chép

Nếu không được định nghĩa, trình biên dịch sẽ tạo ra cấu tử

sao chép ngầm định Cấu tử này sao đối tượng nguồn theo từng

bit sang đối tượng mới

Hàm dựng sao chép trong ví dụ trên không khác gì hàm dựng

sao chép mặc định

sao chép mặc định

 Khi lớp có các thuộc tính con trỏ hoặc tham chiếu, thì hàm

dựng sao chép mặc định chưa đáp ứng được yêu cầu (ví dụ sao

chép mặc định hai con trỏ của 2 đối tượng thì hai đối tượng

dùng chung bộ nhớ con trỏ-> hai đối tượng không độc lập)

Trang 47

Hàm dựng sao chép tạo ra đối tượng mới trong khi toán tử

gán chỉ thay đổi giá trị của đối tượng hiện có

gán chỉ thay đổi giá trị của đối tượng hiện có

point& point::operator=(const point& source){

Trang 48

Định nghĩa lớp- Hàm hủy/ Hủy tử

Hàm hủy thực hiện chức năng ngược lại với hàm dựng

Tự động gọi khi đối tượng bị hủy, hoặc do kết thúc phạm vi tồn

tại của nó hoặc do được cấp phát động và được giải phóng bằng

delete

Hủy tử phải có tên giống tên lớp, nhưng có thêm dấu ~ phía

trước, không có đối số và không có kiểu trả về (kể cả void)

trước, không có đối số và không có kiểu trả về (kể cả void)

point ::~ point()

{

}

Nếu không định nghĩa hàm hủy, thì một hàm hủy mặc định

không làm gì cả được phát sinh Đối với nhiều lớp thì hàm hủy

mặc định là đủ, và không cần đưa vào một hàm hủy mới

Trang 49

Các lớp được định nghĩa với struct và union

Các lớp có thể định nghĩa bằng các từ khóa struct và union

Chỉ có một sự khác nhau là các thành phần của lớp được khai

báo với struct và union có quyền truy cập mặc định là public

Với union, nó chỉ chứa một thành phần dữ liệu tại một thời

Với union, nó chỉ chứa một thành phần dữ liệu tại một thời

điểm

Trang 50

Quá tải/ Nạp chồng/ Định nghĩa lại các toán tử

Cú pháp:

type operator sign (parameters) { /* */ }

Ví dụ:

point operator=(point a);

point operator + (point a);

point operator - (point a);

point operator - (point a);

Ngày đăng: 11/05/2021, 18:56

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm