21
Lập trình hướng đối tượng C++ Giảng viên giảng dạy: Nguyễn Hữu Vân Long

Chuong4 (2)

  • Upload
    ho-loi

  • View
    21

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Chuong4 (2)

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

Giảng viên giảng dạy: Nguyễn Hữu Vân Long

Page 2: Chuong4 (2)

Chương 4Hàm thành viên

Page 3: Chuong4 (2)

BM MTT&TT 3

Tái định nghĩa hàm thành viên

Đối số mặc nhiên

Hàm tại chỗ (inline)

Truyền đối tượng như đối số của hàm

Trị trả về của hàm là đối tượng

Con trỏ this

Hằng (constant)

Nội dung bài giảng

Page 4: Chuong4 (2)

BM MTT&TT 4

Trong 1 lớp, có thể định nghĩa các hàm thành viên trùng tên, nhưng các hàm này phải khác nhau về tham số

=> Quy tắc tái định nghĩa hàm

Tái định nghĩa hàm thành viên

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

class Diem { private: int x, y;

public: Diem(); Diem(int); Diem(int, int); void hien(); void hien(char*);};

Diem::Diem() { x = y = 0; }

Diem::Diem(int nx) { x = nx; y = 0; }

Diem::Diem(int nx, int ny) { x = nx; y = ny; }

void Diem::hien() { cout << "(" << x << "," << y << ")";}

void Diem::hien(char *s) { cout << s; hien();}

void main() { Diem a, b(5), c(1, 1); a.hien(); b.hien("\nB");}

Page 5: Chuong4 (2)

BM MTT&TT 5

Hàm thành viên cũng có thể sử dụng đối số mặc nhiên.

Chú ý quy tắc khai báo đối số mặc nhiên: Tất cả đối số mặc nhiên đều phải nằm cuối hàm.

Đối số mặc nhiên

class Diem { private: int x, y;

public: Diem(int=0, int=0); void hien(char* = "");};

Diem::Diem(int nx, int ny) { x = nx; y = ny; }

void Diem::hien(char *s) { cout << s; cout << "(" << x << "," << y << ")";}

Page 6: Chuong4 (2)

BM MTT&TT 6

Có 2 cách khai báo hàm thành viên là hàm inline

Thêm từ khóa inline vào trước khai báo hoặc định nghĩa hàm.

Định nghĩa hàm thành viên ngay bên trong khai báo lớp.

Hàm inline

class Diem { private: int x, y;

public: Diem(int nx=0, int ny=0) { x = nx; y = ny; }

inline void hien(char* s="");};

inline void Diem::hien(char *s){ cout << s; cout << "(" << x << ", " << y << ")";}

Page 7: Chuong4 (2)

BM MTT&TT 7

Tham số của hàm thành viên có thể có kiểu bất kỳ

Kiểu cơ bản (primitive type): int, float, char,…

Kiểu do người dùng ĐN (user define): struct, class,…

Cách truyền tham số cho các kiểu dữ liệu này cũng như nhau, có 3 cách truyền

Truyền bằng giá trị.

Truyền bằng con trỏ (địa chỉ).

Truyền bằng tham chiếu.

Truyền ĐT cho đối số hàm TV

Page 8: Chuong4 (2)

BM MTT&TT 8

Truyền qua giá trị: Giá trị dữ liệu của tham số thực tế được truyền vào cho hàm

Tham số của hàm thành viên có thể có kiểu bất kỳ.

Một đối tượng có thể được truyền theo tham số.

Truyền ĐT cho đối số hàm TV

class Diem { int x,y;public: Diem(int h=0, int t=0) { x = h; y = t; } char* trung(Diem d) { if(x==d.x && y==d.y) return "Trung"; else return "Ko trung"; }};

void main() { Diem a; Diem b(1); Diem c(1,0); cout << "A va B: " << a.trung(b) << endl;

cout << "B va C: " << b.trung(c) << endl;}

Page 9: Chuong4 (2)

BM MTT&TT 9

Truyền ĐT cho đối số hàm TVmain()

a

x=0 y=0

Diem()trung() {

}

b

x=1 y=0

Diem()trung() {

}

c

x=1 y=0

Diem()trung() {

}

...a.trung(b);b.trung(c); ...

d

x= y=

...

d

x= y=

...

d

x=1 y=0

...

1 0 1 0

x==d.x?

y==d.y?

x==d.x?

y==d.y?

Page 10: Chuong4 (2)

BM MTT&TT 10

Truyền qua địa chỉ: Địa chỉ của tham số thực tế được truyền vào cho tham số hình thức là con trỏ của hàm.

Tiết kiệm ô nhớ cho chương trình (hơn truyền qua giá trị).

Có thể làm thay đổi giá trị của đối tượng truyền vào.

Truyền ĐT cho đối số hàm TV

class Diem { int x,y;public: Diem(int h=0, int t=0) { x = h; y = t; } char* trung(Diem* d) { if(x==d->x && y==d->y) return "Trung"; else return "Ko trung"; }};

void main() { Diem a; Diem b(1); Diem c(1,0); cout << "A va B: " << a.trung(&b) << endl;

cout << "B va C: " << b.trung(&c) << endl;}

Page 11: Chuong4 (2)

BM MTT&TT 11

Truyền ĐT cho đối số hàm TVmain()

a

x=0 y=0

Diem()trung() {

}

b

x=1 y=0

Diem()trung() {

}

c

x=1 y=0

Diem()trung() {

}

...a.trung(&b);b.trung(&c); ...

*d: *d: *d:1004 1008

x==*d.x?

y==*d.y?x==*d.x?

y==*d.y?

&1000 &1004 &1008

& &

Page 12: Chuong4 (2)

BM MTT&TT 12

Truyền qua tham chiếu: Đối tượng là tham số thực tế được truyền vào cho tham số hình thức là tham chiếu của hàm.

Tương tự như truyền qua địa chỉ.

Định nghĩa hàm sẽ đơn giản hơn (như truyền qua giá trị)

Cũng có thể làm thay đổi giá trị của đối tượng truyền vào.

Truyền ĐT cho đối số hàm TV

class Diem { int x,y;public: Diem(int h=0, int t=0) { x = h; y = t; } char* trung(Diem& d) { if(x==d.x && y==d.y) return "Trung"; else return "Ko trung"; }};

void main() { Diem a; Diem b(1); Diem c(1,0); cout << "A va B: " << a.trung(b) << endl;

cout << "B va C: " << b.trung(c) << endl;}

Page 13: Chuong4 (2)

main()

a

x=0 y=0

Diem()trung() {

}

b

x=1 y=0

Diem()trung() {

}

c

x=1 y=0

Diem()trung() {

}

...a.trung(b);b.trung(c); ...

&d: &d: &d:b

x==d.x?

y==d.y?x==d.x?

y==d.y?

& &c

Truyền ĐT cho đối số hàm TV

Page 14: Chuong4 (2)

14

Lớp được xem như là một kiểu dữ liệu do người dùng định nghĩa, nên nó cũng có thể là kiểu dữ liệu trả về của một hàm.

Trị trả về của hàm có thể được truyền bằng:

Giá trị.

Địa chỉ (con trỏ).

Tham chiếu.

Trị trả về của hàm là đối tượng

Page 15: Chuong4 (2)

Trị trả về truyền qua giá trị: Giá trị của đối tượng là trị trả về của hàm sẽ được sao chép sang cho đối tượng nhận giá trị trả về bên ngoài hàm.

Trị trả về của hàm thành viên có thể có kiểu bất kỳ.

Một hàm có thể có trị trả về là một đối tượng.

Trị trả về của hàm là đối tượng

Page 16: Chuong4 (2)

main()

a

x=1 y=2

Diem()doixung() {

}

b

x= y=

...

kq

x=-1 y=-2

Diem()doixung() {

}

...b = a.doixung();c = (a.doixung()).doixung(); ...

kq

x= y=

...

kq

x= y=

...

-1 -2

return kq;

=

-1 -2

c

x= y=

...

1 2

1 2=

Trị trả về của hàm là đối tượng

Page 17: Chuong4 (2)

Trị trả về truyền qua địa chỉ: Địa chỉ của đối tượng là trị trả về của hàm được trả về cho lời gọi hàm để gán cho con trỏ nhận giá trị trả về.

Tránh lãng phí bộ nhớ và thời gian gọi hàm.

Sử dụng phải cẩn thận vì có thể gây ra hiệu ứng phụ

Trị trả về của hàm là đối tượng

class Diem { int x,y;public: Diem(int h=0, int t=0){ x = h; y = t; } Diem* doixung() { Diem *kqua; kqua = new Diem(-x, -y); return kqua; }};

void main() { Diem a(1, 2); Diem *pa; pa = a.doixung(); Diem b; b = *(a.doixung()); ...}

Page 18: Chuong4 (2)

Trị trả về của hàm là đối tượngmain()

a

x=1 y=2

Diem()doixung() {

}

*pa: xxx

...pa = a.doixung();b = *(a.doixung());...

x= y=

...

-1 -2

return kqua;

b

x= y=

...

-1 -2*kqua:

=

xxx

Phải sử dụng cẩn thận!

Diem* doixung() { Diem kqua(-x,-y); return &kqua;}

Page 19: Chuong4 (2)

Trị trả về truyền qua tham chiếu

Tương tự như truyền qua địa chỉ, cú pháp giống truyền qua giá trị

Đa số dùng để trả về một đối tượng toàn cục hay nội dung một con trỏ đã được cấp vùng nhớ trong hàm.

Trị trả về của hàm là đối tượng

class Diem {

...

Diem& doixung() { Diem *kqua; kqua = new Diem(-x, -y); return *kqua; }};

void main() { Diem a(1, 2), b; b = a.doixung();

Diem *pa; pa = &(a.doixung());

...}

Page 20: Chuong4 (2)

Luôn tồn tại trong mọi hàm thành viên không tĩnh

Đây là con trỏ trỏ tới đối tượng đang gọi hàm

Lưu địa chỉ của chính đối tượng đang xét.

Muốn lấy giá trị của chính đối tượng: dùng *this.

Thuộc tính truy cập là private.

Con trỏ *this

class ViDu2 {

int a;

public:

ViDu2(int x) { a= x; }

void InDiaChi() {

cout<<“Dia chi doi tuong : “

<<this<<endl;

cout<< “Dia chi du lieu a : “

<<&a<<endl;

}

};

class Diem {

int x, y;

public:

Diem()

{ x=y=0; }

Diem(int x, int y) {

this->x = x;

this->y = y;

}

};

Page 21: Chuong4 (2)

Hằng dữ liệu: không thay đổi giá trị trong khi thực thi.

Hằng đối tượng: không thay đổi giá trị các thành phần dữ liệu trong đối tượng.

Hàm thành viên hằng:

Có thể thao tác trên hằng đối tượng.

Không làm thay đổi giá trị dữ liệu của đối tượng.

Hàm thành viên hằng

class Diem { int x,y; public: Diem(); void Hien() const; void Doi(int, int);};… … …

void main() { Diem a; const Diem c; // Hằng đối tượng a.Hien(); a.Doi(5,6); c.Hien(); // Gọi hàm hằng c.Doi(10,20); // Sai vì Doi(int,int)

// không là hàm hằng }