Chuong3 c

28
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

Transcript of Chuong3 c

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

BM MTT&TT 2

Chương 3Lập trình hướng đối tượng OOP

p Lớp trong C++

p Đối tượng trong C++

p Một số khái niệm khác++

BM MTT&TT 3

Lớp

Khai báo

Định nghĩa

Thuộc tính và Hàm thành viên

Đối tượng

Khai báo

Sử dụng

Sơ lược hàm xây dựng và hàm hủy

Dữ liệu hàm thành viên tĩnh

Khai thác 1 lớp trong ứng dụng

Nội dung bài giảng

BM MTT&TT 4

Tạo một lớp

Khai báo (class declaration):

Các thuộc tính: tên, kiểu

Các phương thức: tên, đối số, kiểu trả về.

Định nghĩa - Cài đặt các phương thức (hàm thành viên) của lớp

Lớp

BM MTT&TT 5

Khai báo

Lớp

class <Tên lớp> { Thuộc tính truy cập : <Các dữ liệu thành viên> <Các hàm thành viên> Thuộc tính truy cập : <Các dữ liệu thành viên> <Các hàm thành viên> };

Sơ đồ lớp điểm trong không gian 2 chiều

public, protected, private

<kiểu dliệu> <tên t.tính>;

Cú pháp ( Khai báo hàm):

<kiểu dltrả về> <tên hàm>([dsách đối số]);

BM MTT&TT 6

Ví dụ: Viết khai báo cho lớp Điểm trong không gian 2 chiều.

Tên lớp: Diem

Thuộc tính: tọa độ (x, y) kiểu số nguyên.

Một số thao tác trên một Điểm: đặt giá trị cho x, y; hiển thị điểm (tọa độ hoặc vẽ ra màn hình); di chuyển điểm đến một tọa độ mới; lấy tọa độ của một điểm;…

Lớp

class Diem{ private: int x, y;

public: void set(int, int); void display(); void input(); void move(int, int); int getX(); int getY(); };

Khai báo lớp điểm như sau

Default: private

BM MTT&TT 7

Định nghĩa hàm thành viên

Lớp

<Kiểu trả về> <Tên lớp> :: <Tên hàm>( Các tham số + Kiểu ) {

< Khai báo các dữ liệu cục bộ của hàm>

< Thân hàm - Nội dung hàm >

< Câu lệnh return >

}

Toán tử chỉ phạm vi

BM MTT&TT 8

Lớp

BM MTT&TT 9

Đối tượng: là 1 biến có kiểu dữ liệu là Lớp

Tạo đối tượng tương tự như khai báo biến

Dạng biến: <Tên lớp> <Tên đối tượng>;

VD: Diem a, b;

Dạng mảng: <Tên lớp> <Tên mảng>[Kích thước];

VD: Diem mang[10];

Đối tượng

a

x

y

1000H

b

x

y

1004H

mang

x

y

1008H

BM MTT&TT 10

Khởi tạo đối tượng

Dạng con trỏ : <tên lớp> *<tên con trỏ>;

VD: Diem *pa, *ds;

pa= new Diem; ds= new Diem[10];

delete pa; delete[] ds;

Chú ý: Phải cấp và thu hồi vùng nhớ cho con trỏ đối tượng.

Đối tượng

1000[0] [1] [2] [3] [4] [5]

*pa 1024

*pArray 1000 1024

BM MTT&TT 11

Sử dụng đối tượng

Khi khởi tạo đối tượng xong, ta có thể : Truy xuất đến dữ liệu thành viên (public) của đối tượng. Gọi các hàm thành viên của đối tượng.

Đối tượng

BM MTT&TT 12

Phép gán đối tượng:

Dùng toán tử =

Thực chất là gán tương ứng các thành phần dữ liệu của hai đối tượng cho nhau.

Chú ý: chỉ hoạt động chính xác khi thành phần dữ liệu không có con trỏ (Muốn dùng phép gán trong trường hợp đối tượng có dữ liệu thành viên là con trỏ thì phải tái định nghĩa toán tử gán).

Phải định nghĩa lại phép gán khi dữ liệu có con trỏ.

Đối tượng

Diem a, b;

a.set(0, 0);b = a; // b(0,0)

Diem *pa;

pa = new Diem;*pa = a; // *pa(0,0)

BM MTT&TT 13

Phép gán đối tượngx 0

y 0

x 0

y 0

a

*pa 100

b

100x 0

y 0

class Sinhvien { private: char mssv[8]; char *hoten; ...};

Sinhvien a, b;

a.gan(...);

b = a; //!?

1960549

a 100

...1960549

b 100

...

TRANCONGAN

100

Diem a, b, *pa;

a.set(0, 0);

b = a; // b(0,0)pa = new Diem;*pa = a;

BM MTT&TT 14

Hàm xây dựng (Constructor)

Tại sao cần hàm xây dựng ?

Hàm xây dựng - Hàm hủy

hiệu ứng phụ

Cần phải khởi tạo giá trị ban đầu cho các dữ liệu thành viên

BM MTT&TT 15

Hàm xây dựng (constructor)

Là 1 hàm đặc biệt

Tự động được gọi khi đối tượng được tạo ra

Không được gọi trực tiếp, sẽ được gọi khi tạo đối tượng

Mục đích

Khởi tạo giá trị cho các dữ liệu (thuộc tính) của một đối tượng.

Cấp vùng nhớ cho các con trỏ thành viên.

Cú pháp - Prototype: <tên lớp>([dsách tham số]);

Trùng với tên lớp, không có kiểu trả về (kể cả void).

Có thể không có hay có nhiều tham số.

Có thể không có, có 1 hay nhiều hàm xây dựng.

Hàm xây dựng có thể được tái định nghĩa

Hàm xây dựng - Hàm hủy

BM MTT&TT 16

Hàm xây dựng - Hàm hủyclass Diem {

int x,y;

public:

Diem(); // xd mặc nhiên

Diem(int);

Diem(int,int);

...

};

Diem::Diem()

{ x=y=0; }

Diem::Diem(int a)

{ x = y = a; }

Diem::Diem(int h, int t)

{ x=h; y=t; }

void main() {

Diem a; // Goi Diem()

a. InDiem(); // In (0,0)

Diem b(10,5); // Diem(int,int)

Diem c(3); // Diem(int)

Diem *pa = new Diem();

Diem *pb = new Diem(10,5);

Diem *pc = new Diem(3);

Diem ds1[10]; // Goi Diem()

Diem *ds2 = new Diem [10];

// Goi Diem()

...

}

Khai báo các hàm xây dựng

BM MTT&TT 17

class Sinhvien { private: char mssv[8], *hoten; int namsinh; float diemTB;

public: Sinhvien(); Sinhvien(char*, char*, int, float); void nhap(); void inThongtin(); char* xeploai(); float diemTB();};

Sinhvien::Sinhvien() { strcpy(mssv, ""); hoten = new char[50]; diemTB = 0; namsinh=1900;}

Sinhvien::Sinhvien(char *ms, char* ht, int ns, float dtb) { strcpy(mssv, ms); hoten = strdup(ht); namsinh = ns; diemTB = dtb;}

...

void main() { Sinhvien a; a.nhap(); a.inThongtin();

Sinhvien b("1063106", “NHVLONG", 1978, 8.9); b.inThongtin(); cout << "Loai:" << b.xeploai();}

Hàm xây dựng

Hàm xây dựng - Hàm hủy

BM MTT&TT 18

Hàm hủy (destructor)

Là 1 hàm đặc biệt

Tự động được gọi khi đối tượng bị hủy (???)

Không được gọi trực tiếp

Mục đích

Dùng để thu hồi vùng nhớ đã cấp cho các dữ liệu thành viên là con trỏ của đối tượng, khi hủy bỏ đối tượng.

=> delete các con trỏ là dữ liệu thành viên.

=> nếu không có dữ liệu thành viên là con trỏ thì không cần hàm hủy

Cú pháp : ~<Tên lớp> ( ) { … }

Bắt đầu bằng ký hiệu ~

Tên hàm trùng với tên lớp

Không có tham số

Một lớp có thể không có hoặc chỉ có duy nhất 1 hàm hủy.

Hàm xây dựng - Hàm hủy

BM MTT&TT 19

Hàm hủy (distructor)

Cú pháp : ~<Tên lớp> ( ) { … }

Bắt đầu bằng ký hiệu ~

Tên hàm trùng với tên lớp

Không có tham số

Một lớp có thể không có hoặc chỉ có duy nhất 1 hàm hủy.

Hàm xây dựng - Hàm hủy

BM MTT&TT 20

Hàm xây dựng - Hàm hủyclass Diem{ private: int x, y;

public: ... ~Diem();};

Diem::~Diem() { }

class Sinhvien{ private: char mssv[8], *hoten; int namsinh,; float diemTB;

public: ... ~Sinhvien();};

Sinhvien::~Sinhvien() { delete []hoten;}

Lớp Diem không có dữ liệu thành viên là con trỏ hàm hủy rỗng (hoặc không cần hàm hủy)

Thu hồi vùng nhớ đã cấp cho hoten

BM MTT&TT 21

Đối tượng toàn cục - Đối tượng cục bộ

Đối tượng toàn cục

Khai báo ngoài các lớp và ngoài hàm main().

Sẽ được khởi tạo (tự động gọi hàm xây dựng tương ứng) trước khi hàm main() thực thi.

Sẽ được hủy bỏ ( tự động gọi hàm hủy cho đối tượng ) sau khi kết thúc hàm main().

Đối tượng cục bộ

Khai báo trong một hàm.

Sẽ khởi tạo trong khi thực thi hàm đó.

Sẽ được hủy bỏ ( tự động gọi hàm hủy cho đối tượng đó) trước khi hàm kết thúc.

Các loại đối tượng

BM MTT&TT 22

Dữ liệu thành viên tĩnh (static)

Là dữ liệu thành viên dùng chung cho tất cả các đối tượng của cùng 1 lớp => tồn tại độc lập với các đối tượng.

Giống như 1 biến toàn cục.

Phải được khởi tạo bên ngoài của lớp.

Thường được sử dụng để đếm số lượng đối tượng hiện có.

Một số trường hợp sử dụng:

Hằng số liên quan đến Lớp đối tượng. Ví dụ: các hằng số PI, E,… trong lớp Math

Biến toàn cục cho tất cả các đối tượng.Ví dụ: Biến dùng để đếm số đối tượng được tạo ra.

Dữ liệu và hàm thành viên tĩnh

BM MTT&TT 23

Dữ liệu và hàm thành viên tĩnh

Tại thời điểm nàydem = ?

#include <iostream.h>

class DemDT { private: int x, y;

public: static int soDiem; ... Diem() { soDiem++; } ~Diem() { soDiem--; }};

int Diem::soDiem = 0;

void main() { DemDT a1; cout << DemDT::soDiem; //K t qu ?ế ả DemDT a2[4]; cout << DemDT::soDiem; //K t qu ?ế ả DemDT *a3 = new DiemDT(); cout << a.soDiem; //L i ko?ỗ DemDT *a4 = new DiemDT(2); delete a3;}

BM MTT&TT 24

Hàm thành viên tĩnh (static)

Độc lập với các đối tượng

=> khi gọi hàm không cần đối tượng nào

<Tên lớp>::<Tên hàm> (danh sách tham số)

Chỉ cần thêm static vào trước khai báo hàm trong lớp.

Giống như 1 hàm toàn cục.

Dữ liệu và hàm thành viên tĩnh

BM MTT&TT 25

Smf chỉ có thể truy xuất các smd, smf, dữ liệu và hàm bên ngoài lớp. NonSmf có thể truy xuất tất cả, bao gồm cả smf.

Một Smf có thể được gọi thông qua lớp. NonSmf chỉ được gọi sau khi đã tạo ra 1 thể hiện của lớp (đối tượng).

Một Smf không thể được định nghĩa ảo. NonSmf có thể được định nghĩa ảo.

Một Smf không thể truy xuất tới con trỏ “this” của lớp.

Smf không thường xuyên được sử dụng trong chương trình. Tuy nhiên, nó có thể hữu dụng khi ta cần những hàm có thể truy cập được trực tiếp qua lớp.

Khác biệt giữa Smf và NonSmf

BM MTT&TT 26

Tạo lớp

Khai báo lớp: tập tin tiêu đề <tên lớp>.hpp

Định nghĩa lớp: tập tin <tên lớp>.cpp

Sử dụng lớp #include <tập tin tiêu đề>

Khai thác một lớp

Diem.hpp

class Diem { int x, y; public: ...}

Diem.cpp

#include <Diem.hpp>Diem::Diem() { … }Diem::display() { ... }...

Test.cpp

#include <Diem.cpp>void main() { Diem a, b(1,1); a.set(...); ...}

BM MTT&TT 27

Một lớp có thể được #include nhiều lần

Lỗi khi biên dịch.

Khai thác một lớp

Diem.hpp

class Diem { int x, y;};

Diem.cpp

#include <Diem.hpp>Diem::Diem() { … }...

Test.cpp

#include <Diem.cpp>#include <Htron.cpp>

void main() { ... }

Htron.hpp

#include <Diem.hpp>class Hinhtron { Diem tam; ...};

Htron.cpp

#include <Htron.hpp>class Hinhtron { Diem tam; ...};

Có hai khai báo lớp

Diem trong Test.cpp

BM MTT&TT 28

Tránh include một lớp nhiều lần, ta phải dùng kết hợp các chỉ thị tiền xử lý #ifndef, #define, #endif trong khai báo lớp.

Khai thác một lớp

Diem.hpp

#ifndef DIEM_HPP#define DIEM_HPP 1

class Diem { int x, y; public: Diem(); … };#endif

Kiểm tra một hằng số tên DIEM_HPP có tạo chưa. Nếu chưa thì thực hiện tiếp quá trình tiền xử lý. Ngược lại thì ngưng quá trình này.

Tạo một hằng số tên DIEM_HPP với giá trị là 1

Kết thúc chỉ thị #ifndef

Tên hằng số này được chọn sao cho không bị trùng lắp