Tải bản đầy đủ (.pdf) (20 trang)

Bài giảng lập trình hướng đối tượng c++‎ chương 5 hàm xây dựng, hàm hủy và việc khởi tạo đối tượng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (384.31 KB, 20 trang )

Chương 5

HÀM XÂY DỰNG, HÀM HỦY VÀ
VIỆC KHỞI TẠO ĐỐI TƯỢNG

1


Nội dung
• Hàm xây dựng
• Hàm hủy
• Hàm xây dựng sao chép

• Thuộc tính của 1 lớp là đối tượng

2


Hàm xây dựng
• Mục đích: khởi tạo giá trị ban đầu cho đối tượng
– Gán giá trị đầu cho các thuộc tính.
– Cấp vùng nhớ cho con trỏ thành viên.
class Diem {
int x, y;
public:
Diem(int a)
{ x = y = a; }
Diem(int h, int t)
{ x = h; y=t; }
….
};



class PhanSo {
int tu, mau;
public:
PhanSo()
{ tu=0; mau=1; }
PhanSo(int x)
{ tu=x; mau=1; }
PhanSo(int t, int m)
{ tu = t; mau=m; }
….
};
3


Hàm xây dựng
• Ví dụ:
class SinhVien {
class Stack {
char mssv[8];
float *ds;
char* hoten;
int soluong;
int namsinh;
int vitri;
float diemtb;
public:
Cấp vùng
public:
Stack(int max = 10)

nhớ
SinhVien() {
{
cho con trỏ
strcpy(mssv,””);
soluong = max;
hoten = new char[50];
vitri = 0;
ds = new
namsinh = 1980;
diemtb = 0;
float[soluong];
}
}
SinhVien(char*,char*,int,fl
Stack(float* d, int m,
int n);
oat);


};
};
4


Hàm xây dựng

• Nếu khơng có định nghĩa hàm xây dựng:
– Mặc nhiên sẽ tự động có 1 hàm xây dựng khơng tham số.
– Chỉ có 1 cách khởi tạo đối tượng theo dạng không tham số.

class Diem {
int x, y;
public:
void InDiem();
void NhapDiem();
void GanGiaTri(int,
int);
int
GiaTriX();
int
GiaTriY();

};
// Định nghĩa các hàm
thành viên
...

void main() {
Diem
a;
Diem
*pa = new Diem();
Diem
ds1[10];
Diem
*ds2 = new
Diem[20];

}
x

y



a

1000H

Khơng có giá trị
đầu
nên dễ gây ra
hiệu ứng phụ
5


Hàm xây dựng
• Nếu có định nghĩa ít nhất 1 hàm xây dựng:
– Có bao nhiêu hàm xây dựng sẽ có bấy nhiêu cách khởi tạo
đối tượng theo dạng đã định nghĩa.
void main() {
void main() {
PhanSo a;
Stack a;
PhanSo b(3);
Stack b(5);
PhanSo c(2,5);
Stack c[5];
PhanSo d[3];
Stack *pa = new Stack();
Stack *pb = new Stack(40);

PhanSo *pa = new PhanSo;
PhanSo *pa1 = new PhanSo();
Stack *pc = new Stack[40];
PhanSo *pa2 = new PhanSo[5]; float data[40];
for(int i=0;i<10;i++)
PhanSo *pb = new PhanSo(3);
PhanSo *pc = new
data[i]=i;
Stack d(data, 30, 10);
PhanSo(2,5);


6
}
}


Hàm xây dựng
• Trình tự thực hiện:
– Đối tượng được tạo ra trước.
– Hàm xây dựng sẽ gọi sau trên đối tượng.
tu
mau

PhanSo c(2,5);

c
PhanSo
*pa2 = new
PhanSo[5];


Stack
b(5);

1000H
100
0
*pa2

tu
100
0 mau
*pa2
*ds
soluong
vitri





2
5
c
1000H
tu 0 0 0 0 0
mau 1 1 1 1 1

tu
mau


120
*ds
0
5
soluong
0
vitri

1200H

7


Hàm hủy

• Mục đích: thu hồi vùng nhớ đã cấp cho con
trỏ là dữ liệu thành viên => delete con trỏ.

class SinhVien {
char mssv[8];
char* hoten;
int
namsinh;
float diemtb;
public:
SinhVien() {
strcpy(mssv,””);
hoten = new char[50];
namsinh = 1980;

diemtb = 0;
}
~SinhVien() {
delete[] hoten;
}

};

class Stack {
float *ds;
int
soluong;
int
vitri;
public:
Stack(int
max = 10) {
soluong = max;
vitri = 0;
ds = new
float[soluong];
}
~Stack() {
delete[] ds; }

8
};


Hàm hủy


• Thứ tự thực hiện: gọi trước khi hủy đối tượng:
– Kết thúc 1 hàm mà trong đó ta có khởi tạo đối tượng.

– Thu hồi vùng nhớ cho con trỏ đối tượng.
Hàm xây dựng được gọi
void HamMinhHoa() {
Stack a;
Stack *pa = new Stack(8);

delete pa;
Stack *pb = new Stack[5];

delete[] pb;
pb = new Stack(20);

}

Hàm hủy được gọi cho
đối tượng mà pa đang trỏ
tới
Hàm xây dựng được gọi 5
lần
Hàm hủy được gọi 5
lần
Hàm xây dựng được gọi
Hàm hủy được gọi cho a
trước khi kết thúc hàm
HamMinhHoa() 9



Hàm xây dựng sao chép
• Tại sao cần hàm xây dựng sao chép?
– Khởi tạo 1 đối tượng có giá trị giống 1 đối tượng khác.
– Khác với phép gán (dấu =)
• Nếu khơng định nghĩa hàm xây dựng sao chép:
– Ngôn ngữ sẽ tự động tạo ra cho ta: nội dung là gán (=)
tương ứng từng thành phần.
– Không chính xác khi có dữ liệu thành viên là con trỏ.

10


Hàm xây dựng sao chép
Stack a(8);


130
*ds
0
8
soluong
3
vitri
a

Stack b(a);

1300H


130
*ds
0
8
soluong
3
vitri
b

4

3.2

1.4



2 con trỏ sẽ
trỏ
cùng 1 địa chỉ
nếu không
định nghĩa
hàm xây
dựng
sao chép


Hàm xây dựng sao chép

• Cú pháp: <Tên lớp> (const <Tên lớp>&


)

{ Nội dung hàm }

VD: Diem(const Diem& d) { … }

Stack(const Stack& s) { … }

SinhVien(const SinhVien& sv) { … }

• Nội dung:

– Gán tương ứng các thành phần dữ liệu (không là con trỏ).
– Cấp vùng nhớ và sao chép nội dung vùng nhớ từ đối tượng
cho trước.
VD: Diem(const Diem& d) { x=d.x; y=d.y; }
PhanSo(const PhanSo& p) { tu=p.tu;
mau=p.mau; }

12


Hàm xây dựng sao chép
• Ví dụ:
class SinhVien {
char
mssv[8];
char* hoten;
int

namsinh;
float
diemtb;
public:

SinhVien(const SinhVien& s){
strcpy(mssv, s.mssv);
hoten = new char[50];
strcpy(hoten, s.hoten);
namsinh = s.namsinh;
diemtb = s.diemtb;
}

};

SinhVien nva; …
\

mssv[]
*hoten
namsinh
diemtb

1 9 2 0 8 9 1 0
1240
1974

1
8.14
2

24
N
g
u
70
6H
N0 g
u
y
H

y

e

e

n

\

1 9 2 0 8 9 1 0
2760
1974
8.14

SinhVien x(nva);

n








c…
o
p
y

mssv[]
*hoten
namsinh
diemtb
13


Hàm xây dựng sao chép
• Ví dụ:
1
class Stack {
Stack a(8);3…
float
*ds;
*ds 130
0 3 1
int
soluong;
0

soluong 8
04 2. 4. … …
int
vitri;
H
3
vitri
public:
a

copy
Stack(const Stack& s) {
soluong = s.soluong;
*ds 157
1 3 1
vitri = s.vitri;
0
soluong 8
54 2. 4. … …
ds = new float[soluong];
7
3
vitri
for(int i=0; i0
b
ds[i]=s.ds[i];
Stack
b(a);
H

}

};
14


Hàm xây dựng sao chép
• Sử dụng trong các trường hợp:
– Đối tượng được truyền theo giá trị của đối số 1 hàm.
– Trị trả về của hàm là 1 đối tượng.
– Tạo ra 1 đối tượng có giá trị giống 1 đối tượng cho trước.
class A {
int x;
public:
A() { x=0; }
A(const A& a) {
x=a.x;
}
void Hien() {
cout<<“x=“<}
};

A

HamThu(A
A y(x);
return y;
}


x) {

void main() {
A
a,b;
b = HamThu(a);
A
c = b;
A *d = new A(c);
}

Có bao
nhiêu hàm
xây dựng
sao chép
được gọi?

15


Thuộc tính của 1 lớp là đối tượng
• Giới thiệu:
– Thuộc tính của 1 lớp có thể có kiểu bất kỳ.
– Thuộc tính của 1 lớp có thể là đối tượng của 1 lớp khác.
Sử dụng lại 1 lớp, nhưng không phải là thừa kế

class Diem {
int x, y;
public :
Diem();

Diem(int , int);
void Nhap();
void Hien();
void DoiDiem(int,int);
int GiaTriX();
int GiaTriY();
};

class DuongTron {
Diem tam;
int
bankinh;
public:
DuongTron(); ...
void Ve();
void Nhap();
void
DoiDTron(int,int);
float ChuVi();
float DienTich();
16
};


Thuộc tính của 1 lớp là đối tượng
• Cách truy xuất:
– Khi truy xuất đến thuộc tính là đối tượng, phải thơng qua
tên của thuộc tính.
– Lưu ý đến thuộc tính truy cập (public, private, …) của
thành phần dữ liệu và hàm thành viên của lớp tạo ra đối

tượng đó để truy xuất hợp lý.


Thuộc tính của 1 lớp là đối tượng
tam
bankinh

x 10
y 20
7

DuongTron a;

Void DuongTron::Ve() {
cout<<“Tam : “;
tam.Hien();
cout<cout<<“Ban kinh : “
<}
Void DuongTron::Nhap() {
cout<<“Nhap tam : “
<tam.Nhap();
cout<<“Nhap ban kinh : “;
cin>>bankinh;
}
void DuongTron::
DoiDTron(int dx,int dy) {
tam.DoiDiem(dx, dy);

}

18


Thuộc tính của 1 lớp là đối tượng
• Hàm xây dựng:
– Phải khởi tạo cho thuộc tính là đối tượng theo dạng
hàm xây dựng của lớp đó.
DuongTron() : tam()

{ bankinh=0; }
DuongTron(Diem d, int bk) : tam(d)
{ bankinh=bk; }
DuongTron(int x, int y, int bk) : tam(x,y)
{ bankinh=bk; }
DuongTron(const DuongTron& d): tam(d.tam)
{bankinh=d.bankinh;}

19


Thuộc tính của 1 lớp là đối tượng
• Hàm xây dựng:
■ Nếu có nhiều thuộc tính là đối tượng, khởi tạo các đối
tượng này liên tiếp nhau thông qua dấu phẩy (,).


Cú pháp này cho phép áp dụng cả với thuộc tính
thường.


Duongtron(): tam(), bankinh(0)
{}
Duongtron(Diem d, int bk) : tam(d), bankinh(bk)
{}

20



×