TÁI ðỊ NH NGH Ĩ A TÁC T Ử
Ch ươ ng 7
1
Nội dung Nộ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 phép gán (d ấ u =)
• Tái ñị nh ngh ĩ a tác t ử xu ấ t – nh ậ p
2
Giới thiệu
Giớ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);}
Ta cần có cách viết các phép toán theo dạng gần gũi hơn
3
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 )
Phan So c = b + a
cout << a << “ + ”
<< b << “ = ” << c;
• 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.
Giới Giới thiệu thiệu ((tt tt))
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
Trang 2• Các tác t ử có th ể ñị nh ngh ĩ a
– S ố h ọ c: +, -, *, /, … T ă ng gi ả m: ++, , +=, *=, …
– So sánh: <, >, >=, <=, ==, !=
– Phép gán: =
Giới
Giới thiệu thiệu ((tt tt))
– <<, >>, [], new, delete, …
5
Tái ñịnh nghĩa bằng hàm ñộc lập Tá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.
class PhanSo {
int tu,mau;
public :
6
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 ; // Sai
}
Phải ñịnh nghĩa thêm tác tử: PhanSo operator + (int , PhanSo);
Tái ñịnh nghĩa bằng hàm thành viên
Tá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 :
7
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
Tái ñịnh nghĩa phép gán (dấu =) Tá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
class Stack {
float *ds;
void main() {
Stack s1(100);
8
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]; }
};
Stack s1(100);
…
Stack s2(20);
… s2 = s1;
… s1 = s2;
}
Trang 3Tái ñịnh nghĩa phép gán (dấu =)
Tá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;
void main(){
SinhVien a, b, c;
9
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
SinhVien a, b, c;
a.Nhap();
c = b = a; //phép gán
SinhVien d=a; // hxdsc
}
Tái ñịnh nghĩa tác tử xuất Tái ñịnh nghĩa tác tử xuất – – nhập 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) – 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); };
Tái ñịnh nghĩa tác tử xuất
Tái ñịnh nghĩa tác tử xuất – – nhập nhập
• Ví dclassụDiem1 {
int x, y;
public :
…
friend ostream& operator << (ostream& os, Diem p);
friend istream& operator >> (istream& is, Diem & p);
};
ostream& operator << (ostream& os, Diem p)
11
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;
cout << “Gia tri diem B la: ” << b <<endl;}
Tái ñịnh nghĩa tác tử xuất Tái ñịnh nghĩa tác tử xuất – – nhập nhập
• Ví d ụ 2
class SinhVien { char mssv[10], *hoten;
float diemtb;
public :
… friend ostream& operator <<
(ostream& os, SinhVien s) {
SinhVien ptcang;
cout<<“Nhap thong tin: ”; cin >> ptcang;
#include <fstream.h>
12
(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; } };
cin >> ptcang;
cout << “Sinh vien A: ”; cout << ptcang ;
ofstream f1(“MyFile.txt”); f1<<ptcang;
f1.close();
ifstream f2(“MyFile.txt”); SinhVien a1;
f2>>a1;
cout << “Trong file: ”; cout <<a1;
f2.close();}