Bài giảng Lập trình hướng đối tượng C++ - Chương 7: Tái định nghĩa tác tử cung cấp cho người học những kiến thức như: Giới thiệu; Tái định nghĩa bằng hàm độc lập; Tái định nghĩa bằng hàm thành viên; Tái định nghĩa phép gán (dấu =); Tái định nghĩa tác tử xuất – nhập. Mời các bạn cùng tham khảo!
Trang 1TÁI ĐỊNH NGHĨA TÁC TỬ
Chương 7
Trang 2Nội dung
• Giới thiệu
• Tái định nghĩa bằng hàm độc lập
• Tái định nghĩa bằng hàm thành viên
• Tái định nghĩa phép gán (dấu =)
• Tái định nghĩa tác tử xuất – nhập
2
Trang 3Giới thiệu • Tại sao cần tái định nghĩa tác tử?
class PhanSo {
int tu, mau;
public :
PhanSo ( int =0, int =1){…}
void InPs() {…}
int LonHon ( PhanSo x) {
return (tu*x.mau>mau*x.tu);}
PhanSo Cong( PhanSo x) {…}
};
void main() {
PhanSo a(4,9), b(3,7);
if (b.LonHon(a))
cout <<“PS b lon hon a”;
PhanSo c = b.Cong(a);
a.InPs(); cout << “ + ”; b.InPs();
cout << “ = ”; c.InPs();
if ( b > a )
Ta cần có cách viết các phép toán theo dạng gần gũi hơn
Phan So c = b + a
cout << a << “ + ”
<< b << “ = ” << c;
Trang 4• Cơ chế
– C++ cho phép ta tái định nghĩa các tác tử (phép toán).
– Việc tái định nghĩa tác tử thực hiện tương tự như tái định nghĩa hàm.
– Cú pháp:
<Kiểu trả về> operator <tác tử> ( các đối số )
– Có 2 cách dùng để tái định nghĩa tác tử:
• Dùng hàm độc lập
• Dùng hàm thành viên
4
Giới thiệu (tt)
Trang 5• Các tác tử có thể định nghĩa
– Số học: +, -, *, /, … Tăng giảm: ++, , +=, *=, … – So sánh: <, >, >=, <=, ==, !=
– Phép gán: =
– <<, >>, [], new, delete, …
Giới thiệu (tt)
Trang 6Tái định nghĩa bằng hàm độc lập
• Thông thường nên khai báo hàm độc lập là hàm bạn của lớp để có thể truy cập các thành phần private của lớp.
• Tác tử sau khi định nghĩa không có tính giao hoán.
6
class PhanSo {
int tu,mau;
public :
friend PhanSo operator + ( PhanSo , int );
};
PhanSo operator + ( PhanSo x, int n)
{ return PhanSo (x.tu + x.mau*n, x.mau);}
void main() {
PhanSo a(2,5);
PhanSo b = operator +(a,10);
PhanSo c = a + 20 ;
PhanSo d = 20 + a ;
}
Trang 7Tái định nghĩa bằng hàm thành viên
• Đối số đầu tiên của tác tử chính là đối tượng đang xét.
=> Hàm sẽ có số lượng đối số ít hơn so với hàm độc lập.
class PhanSo {
int tu,mau;
public :
PhanSo operator + ( int );
};
PhanSo PhanSo :: operator + ( int n)
{ return PhanSo (tu + mau*n, mau);}
void main() {
PhanSo a(2,5);
PhanSo b = a operator +(10);
PhanSo c = a + 20 ;
PhanSo d = 20 + a ; // Sai
Không thể định nghĩa thêm tác tử bằng hàm thành
viên cho trường hợp này
Trang 8Tái định nghĩa phép gán (dấu =)
• C++ mặc nhiên sẽ có phép gán (dấu = ) bằng cách gán tương ứng từng thuộc tính giữa 2 đối tượng.
• Khi thành phần dữ liệu có con trỏ => phải định nghĩa “=”.
• Phép gán phải định nghĩa bằng hàm thành viên
8
class Stack {
float *ds;
int soluong, vitri;
public :
void operator =(const Stack & s){
soluong = s.soluong;
vitri = s.vitri;
delete [] ds;
ds = new float [soluong];
for ( int i=0; i<vitri; i++) ds[i]= s.ds[i]; }
};
void main() {
Stack s1(100);
…
Stack s2(20);
… s2 = s1;
… s1 = s2;
}
Trang 9Tái định nghĩa phép gán (dấu =)
• Phân biệt giữa phép gán và hàm xây dựng sao chép:
– Phép gán: đối tượng đã tồn tại (có vùng nhớ)
– Hàm xây dựng sao chép: đối tượng chưa có
• Trị trả về của phép gán có thể là chính đối tượng đó.
class SinhVien {
char mssv[9]; char* hoten;
int namsinh; float diemtb;
public :
SinhVien& operator =(const
SinhVien& a){
strcpy(mssv,a.mssv);
delete[] hoten;
hoten = strdup(a.hoten);
namsinh = a.namsinh;
diemtb = a.diemtb;
return *this ; }
Phải copy dữ liệu
Xóa vùng nhớ cũ, cấp vùng nhớ mới và copy dữ liệu
void main(){
SinhVien a, b, c;
a.Nhap();
c = b = a; //phép gán
SinhVien d=a; // hxdsc
}
Trang 10Tái định nghĩa tác tử xuất – nhập
• Dùng để xuất nhập trực tiếp đối tượng qua cin, cout:
VD: PhanSo a(2,5); cout << a << endl;
• Các phép toán nhập (>>), xuất (<<) phải được định nghĩa theo dạng hàm độc lập và thường khai báo là friend
• Thao tác với các dòng (stream) xuất/nhập chuẩn như:
– Bàn phím, tập tin dùng để đọc, … (istream)
– Màn hình, tập tin dùng để ghi, … (ostream)
10
class PhanSo {
int tu, mau;
public :
…
friend ostream& operator << (ostream& os, PhanSo p);
friend istream& operator >> (istream& is, PhanSo & p); };
Trang 11Tái định nghĩa tác tử xuất – nhập
• Ví dụ 1class Diem {
int x, y;
public :
…
friend ostream& operator << (ostream& os, Diem p);
friend istream& operator >> (istream& is, Diem & p); };
ostream& operator << (ostream& os, Diem p)
{ os << “(” << p.x << “,” << p.y <<“)”; return os; } istream& operator >> (istream& is, Diem & p) {
cout << “Nhap hoanh do: ”; is >> p.x;
cout << “Nhap tung do: ”; is >> p.y;
return is;}
void main() {
Diem a(2,10), b;
cout<< “Gia tri diem A la: ” << a <<endl;
cout<< “Nhap gia tri cho diem B: ”<<endl; cin>>b;
Trang 12Tái định nghĩa tác tử xuất – nhập
• Ví dụ 2
12
class SinhVien {
char mssv[10], *hoten;
float diemtb;
public :
…
friend ostream& operator <<
(ostream& os, SinhVien s) {
os<<s.mssv<<endl;
os<<s.hoten<<endl;
os<< s.diemtb<<endl;
return os; }
friend istream& operator >>
(istream& is, SinhVien& s){
is.getline(s.mssv,9);
is.getline(s.hoten,49);
is >> s.diemtb;
return is; }
};
cout <<“Nhap thong tin: ”;
cin >> ptcang;
ofstream f1(“MyFile.txt”); f1<<ptcang;
f1.close();
ifstream f2(“MyFile.txt”);
f2>>a1;
cout <<a1;
f2.close();}
#include <fstream.h>