Bài giảng môn Lập trình hướng đối tượng - Chương 5: Hàm xây dựng, hàm hủy và việc khởi tạo đố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
5 trang |
Chia sẻ: nguyenlam99 | Lượt xem: 1055 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Bài giảng môn Lập trình hướng đối tượng - Chương 5: Hàm xây dựng, hàm hủy và việc khởi tạo đối tượng, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
HÀM XÂY DỰNG, HÀM HỦY VÀ
VIỆC KHỞI TẠO ðỐI TƯỢNG
Chương 5
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;
class PhanSo {
int tu, mau;
3
public:
Diem(int a)
{ x = y = a; }
Diem(int h, int t)
{ x = h; y=t; }
.
};
public:
PhanSo()
{ tu=0; mau=1; }
PhanSo(int x)
{ tu=x; mau=1; }
PhanSo(int t, int m)
{ tu = t; mau=m; }
.
};
• Ví dụ:
class SinhVien {
char mssv[8];
char* hoten;
int namsinh;
float diemtb;
public:
class Stack {
float *ds;
int soluong;
int vitri;
public:
Stack(int max = 10)
Hàm xây dựng
Cấp vùng nhớ
4
SinhVien() {
strcpy(mssv,””);
hoten = new char[50];
namsinh = 1980;
diemtb = 0;
}
SinhVien(char*,char*,int,fl
oat);
};
{
soluong = max;
vitri = 0;
ds = new
float[soluong];
}
Stack(float* d, int m,
int n);
};
cho con trỏ
• 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 main() {
Diem a;
Diem *pa = new Diem();
Hàm xây dựng
5
void InDiem();
void NhapDiem();
void GanGiaTri(int,
int);
int GiaTriX();
int GiaTriY();
};
// ðịnh nghĩa các hàm
thành viên
...
a
x
y
1000H
Diem ds1[10];
Diem *ds2 = new
Diem[20];
}
Không có giá trị
ñầu
nên dễ gây ra
hiệu ứng phụ
• 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() {
PhanSo a;
PhanSo b(3);
void main() {
Stack a;
Stack b(5);
Hàm xây dựng
6
PhanSo c(2,5);
PhanSo d[3];
PhanSo *pa = new PhanSo;
PhanSo *pa1 = new PhanSo();
PhanSo *pa2 = new PhanSo[5];
PhanSo *pb = new PhanSo(3);
PhanSo *pc = new
PhanSo(2,5);
}
Stack c[5];
Stack *pa = new Stack();
Stack *pb = new Stack(40);
Stack *pc = new Stack[40];
float data[40];
for(int i=0;i<10;i++)
data[i]=i;
Stack d(data, 30, 10);
}
• 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
2
5
tu
mau
PhanSo c(2,5);
Hàm xây dựng
7
c c
PhanSo
*pa2 = new
PhanSo[5];
tu
mau
1000H
*pa2
1000
tu
mau
1000H
*pa2
1000
0
1
0
1
0
1
0
1
0
1
0
1200
5
*ds
soluong
vitri
1200H
Stack
b(5);
*ds
soluong
vitri
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:
class Stack {
float *ds;
int soluong;
int vitri;
public:
8
SinhVien() {
strcpy(mssv,””);
hoten = new char[50];
namsinh = 1980;
diemtb = 0; }
~SinhVien() {
delete[] hoten; }
};
Stack(int max = 10) {
soluong = max;
vitri = 0;
ds = new
float[soluong];
}
~Stack() {
delete[] ds; }
};
• 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.
void HamMinhHoa() {
Stack a;
Hàm xây dựng ñược gọi
Hàm hủy ñược gọi cho
Hàm hủy
9
Stack *pa = new Stack(8);
delete pa;
Stack *pb = new Stack[5];
delete[] pb;
pb = new Stack(20);
}
ñố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 hủy ñược gọi cho a
trước khi kết thúc hàm
HamMinhHoa()
Hàm xây dựng ñược gọi
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
*ds
soluong
vitri
1300
8
3
4 3.2 1.4
1300H
Stack a(8);
a
*ds 1300
8
2 con trỏ sẽ trỏ
Stack b(a); soluong
vitri 3
b
cùng 1 ñịa chỉ
nếu không
ñịnh nghĩa
hàm xây dựng
sao chép
• Cú pháp: (const & )
{ Nội dung hàm }
VD: Diem(const Diem& d) { }
Stack(const Stack& s) { }
SinhVien(const SinhVien& sv) { }
Hàm xây dựng sao chép
• 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
• Ví dụ:
class SinhVien {
char mssv[8];
char* hoten;
int namsinh;
float diemtb;
public:
*hoten
namsinh
diemtb
1240
1974
8.14
1240H
SinhVien nva;
91 02 98 \01 mssv[]
Hàm xây dựng sao chép
13
SinhVien(const SinhVien& s){
strcpy(mssv, s.mssv);
hoten = new char[50];
strcpy(hoten, s.hoten);
namsinh = s.namsinh;
diemtb = s.diemtb;
}
};
N g u y e n
2760
1974
8.14
91 02 98 \01
N g u y e n
2760H copy
SinhVien x(nva);
*hoten
namsinh
diemtb
mssv[]
• Ví dụ:
class Stack {
float *ds;
int soluong;
int vitri;
public:
*ds
soluong
vitri
1300
8
3
4 3.2 1.4
1300H
a
Stack a(8);
Hàm xây dựng sao chép
14
Stack(const Stack& s) {
soluong = s.soluong;
vitri = s.vitri;
ds = new float[soluong];
for(int i=0; i<vitri; i++)
ds[i]=s.ds[i];
}
};
Stack b(a);
1570
8
3
4 3.2 1.4
1570H
b
copy
*ds
soluong
vitri
• 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;
A HamThu(A x) {
Hàm xây dựng sao chép
15
public:
A() { x=0; }
A(const A& a) {
x=a.x;
}
void Hien() {
cout<<“x=“<<x;
}
};
A y(x);
return y;
}
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?
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 { class DuongTron {
16
int x, y;
public :
Diem();
Diem(int , int);
void Nhap();
void Hien();
void DoiDiem(int,int);
int GiaTriX();
int GiaTriY();
};
Diem tam;
int bankinh;
public:
DuongTron(); ...
void Ve();
void Nhap();
void
DoiDTron(int,int);
float ChuVi();
float DienTich();
};
• 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
Void DuongTron::Ve() {
cout<<“Tam : “;
tam.Hien();
cout<<endl;
cout<<“Ban kinh : “
<<bankinh<<endl;
}
Void DuongTron::Nhap() {
7
10
20tam
bankinh
x
y
DuongTron a;
Thuộc tính của 1 lớp là ñối tượng
18
cout<<“Nhap tam : “
<<endl;
tam.Nhap();
cout<<“Nhap ban kinh : “;
cin>>bankinh;
}
void DuongTron::
DoiDTron(int dx,int dy) {
tam.DoiDiem(dx, dy);
}
• 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; }
Thuộc tính của 1 lớp là ñối tượng
19
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;}
• 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.
Thuộc tính của 1 lớp là ñối tượng
20
Duongtron(): tam(), bankinh(0)
{}
Duongtron(Diem d, int bk) : tam(d), bankinh(bk)
{}
Các file đính kèm theo tài liệu này:
- tran_quang_hai_bangchapter5_8281.pdf