Tái định nghĩa tác tử xuất

Download Report

Transcript Tái định nghĩa tác tử xuất

Chương 6:
TÁI ĐỊNH NGHĨA
CÁC TÁC TỬ

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

Tái định nghĩa tác tử nhập - xuất
Nguyễn Công Huy – Khoa CNTT&TT
1
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);
}
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();
}
Nguyễn Công Huy – Khoa CNTT&TT
Ta cần có cách viết
các phép toán theo
dạng gần gũi hơn
if ( b > a )
Phan So c = b + a
cout << a << “ + ” << b
<< “ = ” << c;
2
Giới thiệu (tt)

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
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, …
Nguyễn Công Huy – Khoa CNTT&TT
3
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:
...
friend PhanSo operator + (PhanSo,int);
};
PhanSo operator + (PhanSo x, int n)
{ return PhanSo(x.tu + x.mau*n, x.mau); }
void main() {
Phải định nghĩa thêm tác tử:
PhanSo a(2,5);
PhanSo operator + (int , PhanSo);
PhanSo b = operator +(a,10);
PhanSo c = a + 20 ;
PhanSo d = 20 + a ; // Sai
}
Nguyễn Công Huy – Khoa CNTT&TT
4
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:
...
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
}
Nguyễn Công Huy – Khoa CNTT&TT
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
5
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;
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];
}
};
Nguyễn Công Huy – Khoa CNTT&TT
void main() {
Stack s1(100);
…
Stack s2(20);
…
s2 = s1;
…
s1 = s2;
}
6
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;
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;
}
};
Nguyễn Công Huy – Khoa CNTT&TT
void main(){
SinhVien a, b, c;
a.Nhap();
c = b = a; //phép gán
SinhVien d=a; // hxdsc
}
Phải copy dữ liệu
Xóa vùng nhớ cũ, cấp vùng
nhớ mới và copy dữ liệu
7
Tá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)
class PhanSo {
int tu, mau;
public :
…
friend ostream& operator << (ostream&
friend istream& operator >> (istream&
};
Nguyễn Công Huy – Khoa CNTT&TT
os, PhanSo p);
is, PhanSo& p);
8
Tái định nghĩa tác tử xuất – nhập

Ví dụ 1
class 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;
cout<< “Gia tri diem B la: ” << b <<endl;
}
Nguyễn Công Huy – Khoa CNTT&TT
9
Tái định nghĩa tác tử xuất – nhập

Ví dụ 2
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;
}
Nguyễn};
Công Huy – Khoa CNTT&TT
#include <fstream.h>
void main() {
SinhVien ptcang;
cout<<“Nhap thong tin: ”;
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();
}
10