Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

70
true class cout C++ operator catch virtual throw try friend bool cin new inline private OOP delete using false STL public 1 ThS. Đặng Bình Phương [email protected] VCBB © 19.03a this Bộ môn Công nghệ phần mềm Khoa Công nghệ thông tin Trường Đại học Khoa học Tự nhiên PP LT HƯỚNG ĐỐI TƯỢNG THUỘC TÍNH ĐỐI TƯỢNG & PHƯƠNG THỨC

Transcript of Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

Page 1: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

trueclass

cout

C++operator

catch

virtual throw

try

friend bool

cinnew

inline private OOP

deleteusing falseSTL

public

1

T h S . Đ ặ n g B ì n h P h ư ơ n gd b p h u o n g @ f i t . h c m u s . e d u . v n

VCBB© 19.03a

this

Bộ môn Công nghệ phần mềm

Khoa Công nghệ thông tin

Trường Đại học Khoa học Tự nhiên

PP LT HƯỚNG ĐỐI TƯỢNG

THUỘC TÍNH ĐỐI TƯỢNG

& PHƯƠNG THỨC

Page 2: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

2

VC

BB

1 2 3 4 5 6 7

Nội dung

Thuộc tính đối tượng và phương thức

Phương thức tạo lập (constructor)

Phương thức hủy (destructor)

Tham số của phương thức

Định nghĩa phép toán (operator) cho kiểu dữ liệu mới

Phương thức chuyển đổi kiểu dữ liệu (casting method)

Một số vấn đề liên quan khác

Mẫu thiết kế Singleton và áp dụng

#include <iostream>using namespace std;

void main(){

cout << “Hello World”;cout << endl;

Page 3: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

3

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Nhu cầu

Thuộc tính đối tượng và phương thức

Page 4: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

4

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Đặc điểm (trong NNLT C++)

Tên trùng với tên lớp và không có kiểu trả về.

Tự động thực thi khi đối tượng được tạo nhằm

khởi tạo dữ liệu và chuẩn bị những công việc

cần thiết để bắt đầu chu kỳ sống của đối tượng.

Có thể có nhiều phương thức tạo lập nạp chồng

nhau (overloading) được phân biệt theo quy tắc

như việc chồng các hàm (phân biệt nhờ danh

sách tham số truyền vào).

Thuộc tính đối tượng và phương thức

HủyTạo lập Sử dụng

Page 5: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

5

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Phân loại

Phương thức tạo lập mặc định (default constructor)

Không có tham số đầu vào.

Được tự động tạo ra nếu lớp không có bất kỳ

phương thức tạo lập nào được định nghĩa.

Phương thức tạo lập sao chép (copy constructor)

Để tạo ra một đối tượng từ một đối tượng có sẵn.

Phương thức tạo lập người lập trình định nghĩa

Có thể quy định các tham số đầu vào khác

nhau để khởi tạo dữ liệu cho đối tượng.

Thuộc tính đối tượng và phương thức

Page 6: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

6

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Cú pháp khai báo và định nghĩa

Khai báo phương thức tạo lập (tổng quát)

Định nghĩa phương thức tạo lập

Thuộc tính đối tượng và phương thức

1 class-name(param-list);

12345

class-name::class-name(param-list)

{

// Khởi tạo dữ liệu và chuẩn bị những công việc

// cần thiết để bắt đầu chu kỳ sống của đối tượng…

}

Page 7: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

7

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Ví dụ

Khai báo lớp CFraction (tập tin Fraction.h)

Thuộc tính đối tượng và phương thức

1234567891011121314

#ifndef _FRACTION_H

#define _FRACTION_H

class CFraction

{

int m_nNum; // Tử số (numerator)

int m_nDenom; // Mẫu số (denominator)

public:

CFraction(); // Phương thức tạo lập mặc định

CFraction(int); // Phương thức tạo lập dạng tử/1

CFraction(int, int); // Phương thức tạo lập dạng tử/mẫu

};

#endif

Page 8: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

8

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Ví dụ

Cài đặt lớp CFraction (tập tin Fraction.cpp)

Thuộc tính đối tượng và phương thức

1234567891011121314

#include “Fraction.h”

// Phương thức tạo lập mặc định (default constructor)

CFraction::CFraction() { m_nNum = 0; m_nDenom = 1; }

// Phương thức tạo lập dạng tử/1

CFraction::CFraction(int nNum) { m_nNum = nNum; m_nDenom = 1; }

// Phương thức tạo lập dạng tử/mẫu

CFraction::CFraction(int nNum, int nDenom)

{

if (nDenom < 0) { nNum = -nNum; nDenom = -nDenom; }

if (nDenom == 0) { nDenom = 1; }

m_nNum = nNum; m_nDenom = nDenom;

}

Page 9: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

9

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Ví dụ

Một số khai báo hợp lệ

Thuộc tính đối tượng và phương thức

1234567891011121314

CFraction frac1; // ()

CFraction frac2(1506); // (int)

CFraction frac3(12, 8); // (int, int)

CFraction* pFrac1 = new CFraction; // new CFraction()

CFraction* pFrac2 = new CFraction(1506); // (int)

CFraction* pFrac3 = new CFraction(12, 8);// (int, int)

CFraction aFrac1[2]; // () x 2

CFraction aFrac2[2] = {2912, 1706}; // (int) x 2

CFraction aFrac3[2] = {CFraction(2912), CFraction(1706)};

CFraction aFrac4[2] = {CFraction(369), CFraction(156, 128)};

CFraction* paFrac = new CFraction[2]; // () x 2

Page 10: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

10

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Phương thức tạo lập sao chép

Khái niệm

Khởi tạo đối tượng của một lớp dựa trên việc

sao chép một đối tượng sẵn có của lớp đó

(không áp dụng cho phép gán).

Được thực thi khi truyền hoặc trả về đối

tượng của lớp đó theo kiểu tham trị.

Ví dụ

Thuộc tính đối tượng và phương thức

12345

CFraction doSomething(CFraction frac) { /* Xử lý… */ }

CFraction frac1(82, 85), frac2;

CFraction frac3(frac1); // Khởi tạo frac3 từ frac1

CFraction frac4 = frac1; // Khởi tạo frac4 từ frac1

frac2 = doSomething(frac1); // Khởi tạo khi truyền và trả

Page 11: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

11

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Phương thức tạo lập sao chép mặc định

Trong C++, phương thức tạo lập sao chép mặc

định (default copy constructor) được tự động

sinh ra cho lớp đối tượng do người lập trình tự

định nghĩa và giúp sao chép từng thành phần

thuộc tính (member-wise copy) từ đối tượng

nguồn sang đối tượng đích theo dạng từng bit

(bit-wise copy).

Nếu các thành phần dữ liệu là các kiểu con trỏ

thì quá trình sao chép sẽ chỉ sao chép địa chỉ của

con trỏ (shallow copy) chứ không thật sự sao

chép vùng nhớ mà chúng quản lý (deep copy).Thuộc tính đối tượng và phương thức

Page 12: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

12

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Vùng nhớđã bị hủyVùng nhớ

chứa dữ liệu

Hình ảnh minh họa

Thuộc tính đối tượng và phương thức

: CFraction

- m_nNum: int

- m_nDenom: int

: CFraction

- m_nNum: int

- m_nDenom: int

: CDynamicArray

- m_nSize: int

- m_pData: int*

: CDynamicArray

- m_nSize: int

- m_pData: int*

Page 13: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

13

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Cài đặt phương thức tạo lập sao chép

Khai báo phương thức tạo lập sao chép

Lưu ý

Nếu tham số được khai báo ở dạng tham trị

thì phương thức tạo lập sao chép lại được

kích hoạt để sao chép đối tượng này lỗi do

sử dụng phương thức đang được định nghĩa!

Việc sử dụng tham chiếu (&) kết hợp với

const (pass-by-reference-to-const) để đối

tượng không bị sao chép và bị thay đổi.

Thuộc tính đối tượng và phương thức

1 class-name(const class-name&);

Page 14: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

14

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Cài đặt phương thức tạo lập sao chép

Ví dụ cài đặt cho lớp mảng động

Thuộc tính đối tượng và phương thức

12345678910111213

class CDynamicArray

{

int m_nSize;

int* m_panData;

public:

CDynamicArray(const CDynamicArray&);

};

CDynamicArray::CDynamicArray(const CDynamicArray& dynArr) {

m_nSize = dynArr.m_nSize;

m_panData = new int[m_nSize];

for (int i = 0; i < m_nSize; i++)

m_panData[i] = dynArr.m_pansData[i];

}

Page 15: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

15

VC

BB

Phương thức tạo lập (constructor)1 2 3 4 5 6 7

Đối sánh giữa C++, Java và C#

Đọc thêm [OOP] trang 83-87.

Chuỗi phương thức tạo lập (constructor

chaining).

Phương thức tạo lập trong kế thừa.

Xử lý khi có lỗi trong phương thức tạo lập.

Phương thức tạo lập sao chép mặc định.

Phương thức tạo lập tĩnh.

Thuộc tính đối tượng và phương thức

Page 16: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

16

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Nhu cầu

Thuộc tính đối tượng và phương thức

Page 17: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

17

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Đặc điểm (trong NNLT C++)

Tên trùng với tên lớp và có dấu ~ ở phía trước.

Không có tham số đầu vào và giá trị trả về.

Mỗi lớp chỉ có duy nhất một phương thức hủy.

Tự động thực hiện mỗi khi đối tượng của lớp

bị hủy (hết phạm vi sử dụng).

Chỉ được thực hiện một lần duy nhất trong

chu kỳ sống của đối tượng.

Trình biên dịch sẽ tự động tạo phương thức hủy

mặc định (default destructor, không làm gì cả)

nếu lớp không có phương thức hủy nào.

Thuộc tính đối tượng và phương thức

Page 18: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

18

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Cú pháp khai báo và định nghĩa

Khai báo phương thức hủy

Định nghĩa phương thức hủy

Thuộc tính đối tượng và phương thức

1 ~class-name();

1234

class-name::~class-name()

{

// Giải phóng tài nguyên đã cấp phát cho đối tượng…

}

Page 19: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

19

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Ví dụ

Cài đặt phương thức hủy cho lớp mảng động

Thuộc tính đối tượng và phương thức

1234567891011121314

class CDynamicArray

{

int m_nSize;

int* m_panData;

public:

~CDynamicArray();

};

CDynamicArray::~CDynamicArray() {

if (m_nSize > 0)

{

m_nSize = 0;

delete []m_panData;

}

}

Page 20: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

20

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Ví dụ

Cài đặt lớp CTimer

Thuộc tính đối tượng và phương thức

1234567891011121314

#include <ctime>

class CTimer

{

clock_t m_clockStart;

public:

CTimer() { m_clockStart = clock(); }

~CTimer()

{

clock_t clockEnd = clock();

cout << “Elapsed time: ” <<

(clockEnd – m_clockStart) << endl;

}

};

Page 21: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

21

VC

BB

Phương thức hủy (destructor)1 2 3 4 5 6 7

Đối sánh giữa C++, Java và C#

Đọc thêm [OOP] trang 90.

Cơ chế “dọn rác” (garbage collector).

Nguy cơ khi quên hủy tài nguyên đã cấp phát.

Thuộc tính đối tượng và phương thức

Page 22: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

22

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Tham số giá trị (tham trị)

Thuộc tính đối tượng và phương thức

int t = x;x = y;y = t;

…… 03 00 00 00 06 00 00 00

int a = 3

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

int b = 6

int x int yswap

……

18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25

int x int y

03 00 00 00 06 00 00 00

Page 23: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

23

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Tham số con trỏ

Thuộc tính đối tượng và phương thức

int t = *px;*px = *py;*py = t;

……

int a = 3

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

int b = 6

int* px int* pyswap

……

18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25

int* px int* py

0B 00 00 00 0F 00 00 00

03 00 00 00 06 00 00 00

Page 24: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

24

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Tham số tham biến (tham chiếu)

Thuộc tính đối tượng và phương thức

int t = x;x = y;y = t;

……

int a = 3

0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

int b = 6

int &x int &yswap

05 00 00 00 06 00 00 00

Page 25: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

25

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Giá trị mặc định cho các tham số

Xem lại Chương 1 – Phần 3. Vấn đề về giá trị

mặc định của tham số hàm.

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011

class CFraction

{

int m_nNum, m_nDenom;

public:

// CFraction(), CFraction(int), CFraction(int, int)

CPhanSo(int nNum = 0, int nDenom = 1)

{

if (nDenom == 0) { nDenom = 1; }

m_nNum = nNum; m_nDenom = nDenom;

}

};

Page 26: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

26

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Số lượng tham số không biết trước

Xem lại Chương 1 – Phần 6. Vấn đề về hàm có

số lượng tham số không biết trước.

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011

class CDynamicArray

{

int m_nSize;

int* m_panData;

public:

CDynamicArray(int nValue, ...)

{

// Các thao tác khởi tạo mảng từ dãy các số nguyên

// được truyền vào hàm tạo…

}

};

Page 27: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

27

VC

BB

Tham số của phương thức1 2 3 4 5 6 7

Đối sánh giữa C++, Java và C#

Đọc thêm [OOP] trang 107-110.

Tham trị và tham chiếu.

Thuộc tính đối tượng và phương thức

Page 28: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

28

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Nhu cầu và cách thực hiện

Xem lại Chương 1 – Phần 7. Nhu cầu về ký hiệu

phép toán cho kiểu dữ liệu mới nhưng là các

phương thức toán tử thực hiện trên các đối

tượng của lớp (class) thay vì là các hàm toán tử

thực hiện trên biến có kiểu cấu trúc (struct).

Nếu viết toán tử bên trong lớp và toán hạng thứ

nhất là đối tượng thuộc lớp đó thì không liệt kê

trong danh sách tham số của toán tử. Ngược lại

phải liệt kê và sử dụng từ khóa friend để có

thể truy cập các thành phần riêng của đối tượng.

Thuộc tính đối tượng và phương thức

Page 29: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

29

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Hàm bạn (friend function) trong C++

Khái niệm

Hàm không phải thành viên của lớp nhưng có

thể truy cập các thành viên riêng của lớp đó.

Được định nghĩa như một hàm bình thường

nhưng bên trong khai báo lớp mà hàm làm

bạn sẽ có nguyên mẫu hàm (prototype) bắt

đầu bằng từ khóa friend.

Thuộc tính đối tượng và phương thức

12345

return-type func-name(param-list) { /* … */ }

class CFriendTest

{

friend func-name(param-list);

};

Page 30: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

30

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Hàm bạn (friend)

Khái niệm

Hàm không phải thành viên của lớp nhưng có

thể truy cập các thành viên riêng của lớp đó.

Được định nghĩa như một hàm bình thường

nhưng bên trong khai báo lớp mà hàm làm

bạn sẽ có nguyên mẫu hàm (prototype) bắt

đầu bằng từ khóa friend.

Thuộc tính đối tượng và phương thức

12345

class CFriendTest

{

friend func-name(param-list);

};

return-type func-name(param-list) { /* … */ }

Page 31: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

31

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Hàm bạn (friend)

Lưu ý

Hữu ích khi quá tải toán tử hoặc truy cập các

thành viên riêng của hai hay nhiều lớp khác

nhau (hàm là friend của hơn một lớp).

Hàm friend không phải là thành viên của lớp

mà nó làm bạn mà chỉ là hàm thường, do đó:

• Khi định nghĩa hàm không sử dụng toán tử ::

• Không thể gọi hàm bằng cách dùng tên đối tượng

và toán tử truy cập thành viên (toán tử . hoặc ->).

• Không có con trỏ this trong hàm.

• Không thể được kế thừa.Thuộc tính đối tượng và phương thức

Page 32: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

32

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Ví dụ

Toán tử + được viết bên trong lớp

Thuộc tính đối tượng và phương thức

1234567891011121314

class CFraction

{

int m_nNum, m_nDenom;

public:

const CFraction operator+(const CFraction&);

};

const CFraction CFraction::operator+(const CFraction& fracR)

{

CFraction fracResult;

fracResult.m_nNum = this->m_nNum * fracR.m_nDenom

+ fracR.m_nNum * this->m_nDenom;

fracResult.m_nDenom = this->m_nDenom * fracR.m_nDenom;

return fracResult;

}

Page 33: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

33

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Ví dụ

Toán tử + được viết bên ngoài lớp

Thuộc tính đối tượng và phương thức

1234567891011121314

class CFraction

{

int m_nNum, m_nDenom;

public:

friend const CFraction operator+(const CFraction&, const CFraction&);

};

const CFraction operator+(const CFraction& fracL, const CFraction& fracR)

{

CFraction fracResult;

fracResult.m_nNum = fracL.m_nNum * fracR.m_nDenom

+ fracR.m_nNum * fracL.m_nDenom;

fracResult.m_nDenom = fracL.m_nDenom * fracR.m_nDenom;

return fracResult;

}

Page 34: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

34

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Các toán tử có và không thể nạp chồng

Thuộc tính đối tượng và phương thức

Danh sách các toán tử có thể nạp chồng

cho kiểu dữ liệu mới do người lập trình tự định nghĩa

+ - * / % ^ &

| ~ ! = < > +=

-= *= /= %= ^= &= |=

<< >> >>= <<= == != <=

>= && || ++ -- ->* ,

-> [] () new new[] delete delete[]

Danh sách các toán tử không thể nạp chồng

cho kiểu dữ liệu mới do người lập trình tự định nghĩa

Một số toán tử của C . ?: sizeof

Một số toán tử của C++ :: .* typeid

Page 35: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

35

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số quy ước và lời khuyên

Chỉ viết toán tử khi cần thiết (ví dụ làm chương trình

dễ xử lý và dễ đọc hơn…) và phù hợp với thực tế

(ví dụ toán tử nhân 2 ngày với nhau!)

Đảm bảo tính chất của toán tử giống như các tính

chất của các kiểu dữ liệu cơ sở (ví dụ toán tử + thực

hiện phép… trừ!)

Đảm bảo tính nhất quán giữa các cặp toán tử (ví dụ

== và !=, ++ và ++(int), > và <, …)

Ưu tiên viết bên trong lớp nếu phải truy xuất đến

các thành phần thuộc tính của lớp. Ngược lại, ưu

tiên viết bên ngoài lớp.

Thuộc tính đối tượng và phương thức

Page 36: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

36

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số quy ước và lời khuyên

Các toán tử 2 ngôi đối xứng thường được viết dưới

dạng hàm friend (ví dụ toán tử +, -, …)

Các toán tử lvalue phải được viết là phương thức

toán tử non-static ở bên trong lớp (ví dụ toán tử =,

[], (), ->, *=, ++, …)

Sử dụng tham chiếu const cho các đối tượng có

kích thước lớn.

Sử dụng toán tử () để truy xuất phần tử trong ma

trận nhiều chiều.

Tận dụng các phương thức tạo lập một tham số

phục vụ việc ép kiểu ngầm định.

Thuộc tính đối tượng và phương thức

Page 37: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

37

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử gán

C++ tự động cung cấp toán tử gán mặc định

cho lớp đối tượng mới.

Chỉ được gán 2 đối tượng cùng lớp.

Thực hiện theo cơ chế member-wise copy từ

đối tượng nguồn sang đối tượng đích theo

dạng bit-wise copy, do đó cần phải nạp chồng

khi thành phần dữ liệu là các biến con trỏ

sử dụng cấp phát bộ nhớ động.

Không dùng hàm friend khi nạp chồng.

Thuộc tính đối tượng và phương thức

Page 38: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

38

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Cài đặt toán tử gán cho lớp mảng cấp phát động

Thuộc tính đối tượng và phương thức

12345678910111213

public:

CDynamicArray& operator=(const CDynamicArray& dynArr)

{

if (this != &dynArr) // Tránh gán chính nó

{

delete []m_pnData; // Xóa vùng nhớ đang giữ

m_nSize = dynArr.m_nSize;

m_pnData = new int[m_nSize];

for (int i = 0; i < m_nSize; i++)

m_pnData[i] = dynArr.m_pnData[i];

}

return *this;

}

Page 39: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

39

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử chèn (insertion) <<

Thuộc tính đối tượng và phương thức

123456789101112

class CFraction

{

int m_nNum, m_nDenom;

public:

friend ostream& operator<<(ostream&, const CFraction&);

};

ostream& operator<<(ostream& os, const CFraction& frac)

{

os << frac.m_nNum << “/” << frac.m_nDenom;

return os;

}

Page 40: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

40

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử trích (extraction) >>

Thuộc tính đối tượng và phương thức

123456789101112

class CFraction

{

int m_nNum, m_nDenom;

public:

friend istream& operator>>(istream&, CFraction&);

};

istream& operator>>(istream& is, CFraction& frac)

{

is >> frac.m_nNum >> frac.m_nDenom;

return is;

}

Page 41: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

41

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử + viết sai (khác toán tử + gốc)

Thuộc tính đối tượng và phương thức

12345678910111213

class CFraction

{

int m_nNum, m_nDenom;

public:

friend void operator+(CFraction&, const CFraction&);

};

void operator+(CFraction& fracL, const CFraction& fracR)

{

fracL.m_nNum = fracL.m_nNum * fracR.m_nDenom

+ fracR.m_nNum * fracL.m_nDenom;

fracL.m_nDenom = fracL.m_nDenom * fracR.m_nDenom;

}

Page 42: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

42

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử ++ sau viết sai (khác toán tử ++ gốc)

Thuộc tính đối tượng và phương thức

123456789101112

class CFraction

{

int m_nNum, m_nDenom;

public:

CFraction& operator++(int); // Toán tử ++ sau

};

CFraction& CFraction::operator++(int)

{

m_nNum = m_nNum + m_nDenom;

return *this;

}

Page 43: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

43

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Một số ví dụ minh họa

Toán tử ++ sau viết đúng (giống toán tử ++ gốc)

Thuộc tính đối tượng và phương thức

12345678910111213

class CFraction

{

int m_nNum, m_nDenom;

public:

CFraction& operator++(int); // Toán tử ++ sau

};

CFraction& CFraction::operator++(int)

{

CFraction fracResult = *this;

m_nNum = m_nNum + m_nDenom; // ++(*this);

return fracResult;

}

Page 44: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

44

VC

BB

Định nghĩa phép toán (operators) cho kiểu dữ liệu mới1 2 3 4 5 6 7

Đối sánh giữa C++, Java và C#

Đọc thêm [OOP] trang 99-100.

Các quy định nạp chồng toán tử.

Các toán tử có thể nạp chồng.

Thuộc tính đối tượng và phương thức

Page 45: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

45

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Khái niệm và phân loại

Khái niệm

Ép kiểu (casting) là việc chuyển đổi các biến

từ kiểu dữ liệu này sang kiểu dữ liệu khác.

Phân loại (trong NNLT C++)

Ép kiểu ngầm định (implicit casting)

Ép kiểu chỉ định (explicit casting)• Ép kiểu theo chuẩn C (C-style casting), ép kiểu tĩnh (static_cast),

ép kiểu động (dynamic_cast), ép kiểu hằng (const_cast)

và ép kiểu dịch lại (reinterpret_cast)

Phương thức ép kiểu tự định nghĩa• Ép kiểu bằng phương thức tạo lập và ép kiểu bằng toán tử.

Thuộc tính đối tượng và phương thức

Page 46: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

46

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Ép kiểu ngầm định

Sự tăng cấp (kiểu dữ liệu) trong biểu thức (chỉ

chuyển đổi tạm thời, nội bộ)

Các thành phần cùng kiểu thì kết quả là kiểu

chung, ví dụ:

• 2 / 4 => 0 (int / int => int)

• 2.0 / 4.0 => 0.5 (float / float => float)

Các thành phần khác kiểu thì kết quả là kiểu

bao quát nhất (char < int < long < float <

double), ví dụ:

• 2.0 / 4 => 2.0 / 4.0 => 0.5

(float / int => float / float => float)Thuộc tính đối tượng và phương thức

Page 47: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

47

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Ép kiểu ngầm định

Trong phép gán, biểu thức ở vế phải luôn được

tăng cấp (hay giảm cấp) tạm thời cho giống biểu

thức ở vế trái và có thể làm mất tính chính xác

của số nguyên khi chuyển sang số thực!

Thuộc tính đối tượng và phương thức

123456

int i, j = 3;

float f = 1.23;

i = f; // f tạm thời giảm cấp thành int

f = i; // i tạm thời nâng cấp thành float

f = j; // j tạm thời nâng cấp thành float, f = 2.999995

Page 48: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

48

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Ép kiểu chỉ định

Xem chi tiết trong [OOP] trang 110-119.

Ép kiểu theo chuẩn C (C-style casting).

Ep kiểu tĩnh (static_cast).

Ép kiểu động (dynamic_cast).

Ép kiểu hằng (const_cast).

Ép kiểu dịch lại (reinterpret_cast).

Thuộc tính đối tượng và phương thức

Page 49: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

49

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Phương thức ép kiểu tự định nghĩa

Ép kiểu bằng phương thức tạo lập (1 tham số)

Thuộc tính đối tượng và phương thức

1234567891011121314

class CFraction

{

int m_nNum, m_nDenom;

public:

CFraction() { m_nNum = 0; m_nDenom = 1; }

CFraction(int nNum) { m_nNum = nNum; m_nDenom = 1; }

// Các phương thức khác…

};

void main()

{

CFraction frac1 = 2912; // CFraction(2912)

CFraction frac2; // CFraction()

frac2 = 1706; // CFraction(1706), operator=

}

Page 50: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

50

VC

BB

Phương thức chuyển đổi kiểu dữ liệu (casting methods)1 2 3 4 5 6 7

Phương thức ép kiểu tự định nghĩa

Ép kiểu dữ liệu bằng toán tử

Thuộc tính đối tượng và phương thức

1234567891011121314

class CFraction

{

int m_nNum, m_nDenom;

public:

CFraction(int nNum, int nDenom) { m_nNum = nNum; m_nDenom = nDenom; }

operator int() const { return m_nNum / m_nDenom; }

};

void main()

{

CFraction frac(2912, 1706);

int nResult1 = frac; // Ép kiểu ngầm định

int nResult2 = int(frac); // Ép kiểu chỉ định

int nResult3 = (int)frac; // Ép kiểu chỉ định

}

Page 51: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

51

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Thành phần tĩnh (static)

Khái niệm

Thành phần dữ liệu tĩnh (static data member

hay class-level member) và phương thức tĩnh

(static method hay class-level method) của

lớp không phụ thuộc vào một đối tượng cụ

thể nào cả mà là thành phần chung cho tất cả

các đối tượng của lớp tương ứng.

Cú pháp

Thuộc tính đối tượng và phương thức

12

static type-name var-name;

static return-type method-name(param-list);

Page 52: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

52

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Thành phần tĩnh (static)

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011121314

class CStaticTest

{

static int s_nCount; // Số lượng đối tượng

public:

static int getCount() { return s_nCount; }

CStaticTest() { ++s_nCount; }

~CStaticTest() { --s_nCount; }

};

int CStaticTest::s_nCount = 0; // Bỏ từ khóa static

void main()

{

CStaticTest staticTest1, staticTest2;

cout << “Number of objects: ” << CStaticTest::getCount();

}

Page 53: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

53

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Thành phần dữ liệu có kiểu là lớp

Khi A có thành phần dữ liệu là một đối tượng có

kiểu thuộc lớp B thì:

Khi A được tạo lập Phương thức tạo lập

của lớp B được thực hiện trước.

Khi A bị hủy Phương thức hủy của lớp B

được thực hiện sau.

Ký hiệu UML (quan hệ association)

Thuộc tính đối tượng và phương thức

BA

- b: B

Page 54: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

54

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Thành phần dữ liệu có kiểu là lớp

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011121314

class CB

{

public:

CB() { cout << “Constructing CB...” << endl; }

~CB() { cout << “Destructing CB...” << endl; }

};

class CA

{

CB m_b;

public:

CA() { cout << “Constructing CA...” << endl; }

~CA() { cout << “Destructing CA...” << endl; }

};

void main() { CA a; }

Page 55: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

55

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Danh sách khởi tạo (initializers)

Khái niệm

Khởi tạo giá trị cho các thành phần dữ liệu

của lớp (thứ tự thực hiện trong khai báo lớp).

Là cách duy nhất được sử dụng trong các

trường hợp không thể tạo lập giá trị ban đầu

cho các thành phần dữ liệu có kiểu hằng số,

tham chiếu hay đối tượng của lớp không có

phương thức tạo lập mặc định.

Cú pháp

Thuộc tính đối tượng và phương thức

1 class-name(param-list) : var-name-1(arg), var-name-2(arg)

Page 56: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

56

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Danh sách khởi tạo (initializers)

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011121314

class CA

{

int m_nX;

public:

CA(int nX) { m_nX = nX; }

};

class CTest

{

const int m_nK;

CA& m_aRef;

CA m_a;

public:

CTest(int nK, A& aRef) : m_nK(nK), m_aRef(aRef), m_a(nK) { };

};

Page 57: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

57

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Phương thức có thuộc tính const

Khái niệm

Cam kết sẽ không làm thay đổi trạng thái hay

giá trị của các thành phần dữ liệu của lớp.

Đối tượng bình thường có thể gọi được

phương thức bình thường hoặc const.

Đối tượng const có thể gọi phương thức

const nhưng không thể gọi phương thức

bình thường.

Cú pháp

Thuộc tính đối tượng và phương thức

1 return-type method-name(param-list) const;

Page 58: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

58

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Phương thức có thuộc tính const

Ví dụ

Thuộc tính đối tượng và phương thức

1234567891011121314

class CA

{

public:

void test() { }

void testConst() const { }

};

void doSomething(CA a1, const CA& a2)

{

a1.test(); // OK, a1 non-const

a1.testConst(); // OK, a1 non-const

a2.test(); // Lỗi, a2 const, test() non-const

a2.testConst(); // OK, testConst() const

}

Page 59: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

59

VC

BB

Một số vấn đề liên quan khác1 2 3 4 5 6 7

Luật bộ ba (rule of three)

Luật bộ ba (“rule of three”, “the Law of The Big

Three” hay “The Big Three”), được Marshall

Cline đề xuất năm 1991, là quy tắc trong C++

nói rằng “nếu một lớp đối tượng định nghĩa lại

một trong ba phương thức gồm phương thức

hủy – tạo lập sao chép – toán tử gán thì lớp đối

tượng này nên định nghĩa luôn cả ba phương

thức đó một cách tường minh”.

Thường được áp dụng trong các lớp đối tượng

có thuộc tính thành viên là con trỏ sử dụng bộ

nhớ được cấp phát động.Thuộc tính đối tượng và phương thức

Page 60: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

60

VC

BB

Áp dụng1 2 3 4 5 6 7

Mẫu thiết kế Singleton và áp dụng

Mẫu thiết kế (design pattern)

Là lời giải mẫu cho các bài toán giống nhau.

Cuốn sách nổi tiếng “Design Patterns –

Elements of Reusable Object-Oriented

Software (năm 1994)

• Nhóm 4 tác giả (Gang of Four

– GoF) bao gồm Erich Gamma,

Richard Helm, Ralph Johnson

và John Vlissides.

• Gồm 23 mẫu thiết kế

(được gọi là mẫu GoF).

Thuộc tính đối tượng và phương thức

Page 61: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

61

VC

BB

Áp dụng1 2 3 4 5 6 7

Mẫu thiết kế Singleton và áp dụng

Khái niệm

Là mẫu thiết kế trong lập trình hướng.

Áp dụng mẫu này lên một lớp sẽ đảm bảo

lớp này chỉ có nhiều nhất một đối tượng

được tạo ra trong suốt chương trình.

Sơ đồ UML

Thuộc tính đối tượng và phương thức

CSingelton

- static CSingleton s_pInstance

- CSingleton()

+ getInstance(): CSingleton

CSingleton getInstance()

{

return s_pInstance;

}

Page 62: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

62

VC

BB

Áp dụng1 2 3 4 5 6 7

Mẫu thiết kế Singleton và áp dụng

Ý tưởng cài đặt (các vấn đề cần giải quyết)

Đặt các phương thức tạo lập dạng privateđể người dùng không thể tự ý tạo đối tượng

mới (phải định nghĩa phương thức tạo lập để

tránh sử dụng phương thức tạo lập mặc định)

Tạo sẵn một đối tượng CSingleton duy nhất

(nếu có) ở dạng static để người dùng chỉ

được phép sử dụng đối tượng đã có sẵn này

(lấy đối tượng thông qua một phương thức

static mà ta cung cấp).

Thuộc tính đối tượng và phương thức

Page 63: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

63

VC

BB

Áp dụng1 2 3 4 5 6 7

Mẫu thiết kế Singleton và áp dụng

Cài đặt (nên chia mã nguồn thành nhiều tập tin)

Thuộc tính đối tượng và phương thức

1234567891011121314

class CSingleton

{

static CSingleton* s_pInstance; // Đối tượng duy nhất

CSingleton() { } // Phương thức tạo lập

public:

static CSingleton* getInstance();

};

CSingleton* CSingleton::s_pInstance = NULL;

static CSingleton* getInstance() // Phương thức lấy

{ // đối tượng của lớp

if (s_pInstance == NULL) s_pInstance = new CSingleton();

return s_pInstance;

}

void main() { CSingleton* pObj = CSingleton::getInstance(); }

Page 64: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

64

VC

BB

Áp dụng1 2 3 4 5 6 7

Mẫu thiết kế Singleton và áp dụng

Thảo luận về các ứng dụng trong thực tế và

biến thể “Multi”-ton của mẫu Singleton.

Thuộc tính đối tượng và phương thức

Page 65: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

65

VC

BB

1 2 3 4 5 6 7

Một số thuật ngữ

bitwise copy: tương tự như member-wise copy.

casting: ép kiểu.

const casting: ép kiểu hằng

constructor: phương thức tạo lập.

C-style casting: ép kiểu theo chuẩn C.

deep copy: khác với shallow copy, sao chép đầy đủ các thành

phần (kể cả sao chép các vùng nhớ mà các thành phần con trỏ

đang trỏ tới).

default constructor: phương thức tạo lập mặc định.

design pattern: mẫu thiết kế.

destructor: phương thức hủy.

dynamic casting: é kiểu động.

explicit casting: ép kiểu chỉ định.

Thuộc tính đối tượng và phương thức

Page 66: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

66

VC

BB

1 2 3 4 5 6 7

Một số thuật ngữ

formal argument: tham số hình thức (gọi tắt là tham số).

implicit casting: ép kiểu ngầm định.

initializers: danh sách khởi tạo cho phương thức tạo lập.

member-wise copy: sao chép các thành viên.

operator: toán tử.

reinterpret casting: ép kiểu dịch lại.

shallow copy: tương tự như member-wise copy.

static casting: ép kiểu tĩnh.

static constructor: phương thức tạo lập tĩnh.

static member, class-level member: thành phần tinh của lớp,

chung cho mọi đối tượng của lớp.

static method, class-level method: phương thức tĩnh của lớp,

phương thức chung cho mọi đối tượng của lớp.

virtual method: phương thức ảo.Thuộc tính đối tượng và phương thức

Page 67: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

67

VC

BB

1 2 3 4 5 6 7

Tài liệu tham khảo

[OOP] Chương 3 – Thuộc tính đối tượng và

phương thức (trang 76-134)

[Primer] Chapter 10 – Objects and Classes

Class Constructors and Destructors (trang 463-476)

Knowing Your Objects: The this Pointer (trang 477-482)

[Primer] Chapter 11 – Working with Classes

Operator Overloading & Introducing Friends(trang 502-541)

Automatic Conversions and Type Casts

for Classes (trang 541-556)

[Primer] Chapter 15 – Friends, Exceptions, and More

Type Cast Operators (trang 848-852)

Thuộc tính đối tượng và phương thức

Page 68: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

68

VC

BB

1 2 3 4 5 6 7

Bài tập

Bài tập 4.1: Cài đặt lớp đồng hồ bấm giờ để xác

định thời gian (số giây) trôi qua (CStopWatch)

hỗ trợ một số hành động như sau:

Tự động thiết lập thời gian ban đầu bằng 0.

Bắt đầu (start), dừng hẳn (stop), tạm dừng

(pause), tiếp tục (resume) tính thời gian trôi qua.

Hiển thị (show) thời gian đã trôi qua ở lần gần

nhất (tự động gọi mỗi khi pause và stop).

Tự động hiển thị thời gian đã trôi qua từ khi

bắt đầu sinh ra đến khi khi đối tượng bị hủy.

Thuộc tính đối tượng và phương thức

Page 69: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

69

VC

BB

1 2 3 4 5 6 7

Bài tập

Bài tập 4.2 đến 4.6: Bổ sung các phương thức

tạo lập, phương thức hủy thích hợp và nạp

chồng các toán tử cơ bản cho các bài tập:

2.6: Lớp phân số (CFraction).

2.7: Lớp đơn thức (CMonomial).

2.10: Lớp ngày (CDate).

3.1: Lớp học sinh (CStudent) sử dụng lớp

string.

3.2: Lớp mảng (CDynamicArray) sử dụng lớp

vector.

Thuộc tính đối tượng và phương thức

Page 70: Pplthdt c04 thuoc_tinhdoituong_phuongthuc_v13.09a

70

VC

BB

1 2 3 4 5 6 7

Bài tập

Bài tập 4.7: Xây dựng lớp số phức (CComplex)

hỗ trợ một số phương thức cơ bản (bao gồm

các phương thức tạo lập và phương thức hủy)

và nạp chồng các toán tử cơ bản.

Bài tập 4.8: Cài đặt lớp các thuật toán sắp xếp

tăng dần các số thực (CSingleSortAlgorithm)

chỉ cho phép thực hiện một phương pháp

sắp xếp đã chọn cho toàn bộ chương trình.

Bài tập 4.9: Cài đặt lớp cung cấp các thuật toán

sắp xếp tăng dần không cần tạo ra đối tượng

khi sử dụng (CStaticSortAlgorithm).Thuộc tính đối tượng và phương thức