Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/, )
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
29 trang |
Chia sẻ: lylyngoc | Lượt xem: 3352 | Lượt tải: 3
Bạn đang xem trước 20 trang tài liệu Chương 4: Đa năng hoá toán tử, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ĐH CÔNG NGHỆ THÔNG TIN
Số tiết lý thuyết: 45 tiết
Số tiết thực hành: 30 tiết
1
2
Chương 1: Tổng quan về OOP
Chương 2: Lớp & đối tượng
Chương 3: Hàm và hàm đa năng trong OOP
Chương 4: Đa năng hóa toán tử
Chương 5: Sự kế thừa và tính đa hình
Nội dung môn học:
3
Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/,…)
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
Chương 4: Đa năng hoá toán tử
4
Khái niệm đa năng hóa toán tử
Khái niệm
Ví dụ
Cú pháp
Đặc điểm
Khái niệm:
Là khả năng kết hợp một toán tử đã có (+,-
,*,/,>,<,..) với một hàm thành viên và dùng nó
với các đối tượng của lớp như là những toán
hạng.
Ví dụ:
Ưu điểm của đa năng hoá toán tử?
Giúp cho chương trình dễ hiểu và dễ truy
tìm lỗi
Chương 4: Đa năng hoá toán tử
void main(){
Phanso a,b,c,d;
c=a.Cong(b);
d=c.Nhan(a.Cong(b))
}
void main(){
Phanso a,b,c,d;
c=a+b;
d=(a+b)*c;
}
5
Khái niệm đa năng hóa toán tử
Khái niệm
Ví dụ
Cú pháp
Đặc điểm
Cú pháp:
operator@(DS_đối số)
Trong đó: @ là toán tử cần đa năng
Ví dụ:
Đặc điểm:
Không được phép thay đổi chức năng cơ
bản,ý nghĩa nguyên thủy của toán tử hoặc
thay đổi thứ tự ưu tiên của chúng.
Các toán tử không thể đa năng hóa:
Chương 4: Đa năng hoá toán tử
Cách khai báo trước: Phanso cong(Phanso)
Cách khai báo đa năng: Phanso operator+(Phanso)
. .* :: ?: sizeof
6
Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/,…)
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
Chương 4: Đa năng hoá toán tử
7
Đa năng hóa toán tử một ngôi (++,--)
Khái niệm
Đặc điểm
Cú pháp
Ví dụ
Khái niệm:
Toán tử một ngôi là gì?
Đặc điểm:
Các toán tử này được sử dụng theo 2 cách: toán
tử đứng trước (prefix) (++a) hay toán tử đứng
sau (postfix) (a++)
Ví dụ: cho biết kết quả của CT sau
Chương 4: Đa năng hoá toán tử
void main(){
int a,b;
a=5;
a++;
cout<<a;
++a;
cout<<a;
}
void main(){
int a,b;
a=5;
b=++a;
cout<<a<<" "<<b;
a=5;
b=a++;
cout<<a<<" "<<b;
}
// a=6
// a=7
// a=6, b=6
// a=6, b=5
8
Đa năng hóa toán tử một ngôi (++,--)
Khái niệm
Đặc điểm
Cú pháp
Ví dụ
Cú pháp khai báo trong lớp:
Toán tử đứng trước (prefix):
operator++()
Toán tử đứng sau (postfix):
operator++(int)
Định nghĩa bên ngoài lớp:
::operator++()
{
….
}
Ví dụ:
Chương 4: Đa năng hoá toán tử
Tham số int được gọi là tham số
giả (chỉ định toán tử đứng sau)
9
Chương 4: Đa năng hoá toán tử
class Phanso{
private:
int tu,mau;
public:
Phanso(int t=0,int m=1);
Phanso operator++();
Phanso operator++(int);
void xuat();
};
Phanso::Phanso(int t,int m){
tu=t; mau=m;
}
Phanso Phanso::operator++(){
tu=tu+mau;
return *this;
}
Phanso Phanso::operator++(int){
Phanso temp=*this;
tu=tu+mau;
return temp;
}
void Phanso::xuat(){
cout<<tu<<"/"<<mau<<endl;
}
void main(){
Phanso a(1,2),b;
a++;
a.xuat();
++a;
a.xuat();
b=++a;
a.xuat();
b.xuat();
b=a++;
a.xuat();
b.xuat();
cout<<endl;
system("pause");
}
// KQ: a=3/2
// KQ: a=5/2
// KQ: a=7/2 và b=7/2
// KQ: a=9/2 và b=7/2
10
Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/,…)
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
Chương 4: Đa năng hoá toán tử
11
Đa năng hóa toán tử hai ngôi
Khái niệm
Cú pháp
Ví dụ
Khái niệm:
Toán tử hai ngôi là gì?
Cú pháp:
Cách 1: dùng 1 đối số
operator(đối số thứ hai)
Cách 2: dùng 2 đối số bằng cách dùng hàm bạn friend
friend operator ( đối số thứ
nhất,đối số thứ hai)
Ví dụ:
Xây dựng lớp phân số giải quyết các trường hợp sau:
Phanso a(1,2),b(3,2),c;
c=a+b;
c=a+5;
c=5+a;
Chương 4: Đa năng hoá toán tử
12
Chương 4: Đa năng hoá toán tử
Cách 1: dùng 1 đối số
class PS{
private:
int tu,mau;
public:
PS(int t=0,int m=1){tu=t;mau=m;}
PS operator+(PS);
};
PS PS:: operator+(PS p){
PS kq;
kq.tu=tu*p.mau+p.tu*mau;
kq.mau=mau*p.mau;
return kq;
}
void main(){
PS a(1,2),b(1,2),c(3,4),d;
d=a+b+c;
}
Cách 2: dùng hàm bạn friend
class PS{
private:
int tu,mau;
public:
PS(int t=0,int m=1){tu=t;mau=m;}
friend PS operator+(PS,PS);
};
PS operator+(PS a,PS b){
PS kq;
kq.tu=a.tu*b.mau+a.tu*b.mau;
kq.mau=a.mau*b.mau;
return kq;
}
void main(){
PS a(1,2),b(1,2),c(3,4),d;
d=a+b+c;
}
13
Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/,…)
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
Chương 4: Đa năng hoá toán tử
14
Định nghĩa lại phép gán (=)
Khái niệm
Lý do?
Cú pháp
Ví dụ
Khái niệm:
Phép gán “=” là gì?
Lý do:
Định nghĩa lại phép gán “=” để giải quyết các trường hợp sau:
Vấn đề con trỏ Null trong cấp phát động(Buổi 2)
Vấn đề chuyển đổi kiểu (Buổi 2)
Cú pháp:
operator=(DS_Đối số_nếu có)
Ví dụ:
Chương 4: Đa năng hoá toán tử
15
Chương 4: Đa năng hoá toán tử
Vấn đề con trỏ Null trong cấp phát động:
class String{
private:
char *p;
public:
String(char *s=“”){p=strdup(s);}
~String(){delete p;}
};
void main(){
String s1(“Hello”);
String s2;
s2=s1;
}
Hello s1:p
s2:p
Giải quyết:
class String{
private:
char *p;
public:
String(char *s=“”){p=strdup(s);}
String& operator=(const String&);
~String(){delete p;}
};
String& String::operator=(const String &s){
p=strdup(s.p);
return (*this);
}
Hello
Hello s1:p
s2:p
Khi kết thúc chương trình s1 giải phóng
vùng nhớ làm cho s2 trỏ vào vùng nhớ
NULL
16
Chương 4: Đa năng hoá toán tử
Vấn đề chuyển đổi kiểu:
class PS{
private:
int tu,mau;
public:
PS(int t=0,int m=1){
tu=t;mau=m;
}
};
void main(){
PS a(1,2);
PS b=3;
}
Giải quyết:
class PS{
private:
int tu,mau;
public:
PS(int t=0,int m=1){
tu=t;mau=m;
}
PS operator=(int);
};
PS PS::operator=(int t){
return PS(t,1);
}
void main(){
PS a(1,2);
PS b=3;
}
Khi gặp câu lệnh gán như trên, CT lần
lượt thực hiện các thao tác sau:
Có định nghĩa phép gán “=” tương
ứng hay không?
Hàm khởi tạo chuyển đổi kiểu có
hay không?
// Error
17
Khái niệm đa năng hóa toán tử
Đa năng hóa toán tử một ngôi (++,--)
Đa năng hóa toán tử hai ngôi (+,-,*,/,…)
Định nghĩa lại phép gán (=)
Đa năng hóa toán tử nhập/xuất (>>,<<)
Chương 4: Đa năng hoá toán tử
18
Đa năng hóa toán tử nhập/xuất (>>,<<)
Khái niệm
Cú pháp
Ví dụ
Khái niệm:
Là cách thức để các toán tử nhập/xuất (>>,<<)
có thể thực hiện được trên các đối tượng người
dùng.
Cú pháp:
Đa năng hóa toán tử xuất:<<
friend ostream& operator &)
Đa năng hóa toán tử nhập:>>
friend istream& operator >>(istream &, &)
Ví dụ:
Chương 4: Đa năng hoá toán tử
19
Chương 4: Đa năng hoá toán tử
Đa năng hoá toán tử nhập/xuất (>>,<<) cho lớp phân số:
void main(){
PS a(1,2);
PS b;
cin>>b;
cout<<b;
}
class PS{
private:
int tu,mau;
public:
PS(int t=0,int m=1){tu=t;mau=m;}
friend ostream& operator <<(ostream &,const PS&);
friend istream& operator >>(istream &, PS&);
};
ostream& operator <<(ostream & os,const PS& p){
os<<p.tu<< “/ "<<p.mau;
return os;
}
istream& operator >>(istream & is, PS& p){
cout<< "Nhap tu: ";
is>>p.tu;
cout<< "Nhap mau: ";
is>>p.mau;
return is;
}
ĐH CÔNG NGHỆ THÔNG TIN
20
ĐH CÔNG NGHỆ THÔNG TIN
21
22
Câu 1: Cho Phát biểu nào sau đây là ĐÚNG trong đa năng
hoá toán tử (operator overloading)
Bài tập trắc nghiệm
A. Có thể thay đổi kết quả thực hiện của các toán tử trên các kiểu dữ liệu cơ sở
(built-in).
B. Có thể định nghĩa thêm toán tử mới ngoài những toán tử đã có trong C++.
C. Có thể thay đổi số lượng tham số (số ngôi) của các toán tử.
D. Không thể thay đổi độ ưu tiên của các toán tử.
23
Câu 2: Toán tử nào có thể được viết lại (overloaded trong C++
Bài tập trắc nghiệm
A. = (toán tử gán)
B. ?: (toán tử điều kiện)
C. sizeof (toán tử xác định kích thước dữ liệu)
D. :: (toán tử phạm vi)
24
Câu 3: Để đa năng hoá toán tử >> dùng để nhập các thông tin
của đối tượng thuộc class Data (ví dụ như: cin>>dataToPrint).
Dòng đầu tiên trong hàm cài đặt toán tử là:
Bài tập trắc nghiệm
A. ostream operator>>(ostream &input,const Data &dataToPrint)
B. ostream operator>>(istream &input,const Data &dataToPrint)
C. istream &operator>>(istream &input, Data dataToPrint)
D. istream &operator>>(istream &input, Data &dataToPrint)
25
Câu 4: Xét đoạn chương trình khai báo class Data như sau:
class Data{
private: int a;
public:
Data operator --(int);
void Giam(){ a=a-1;}
};
Bài tập trắc nghiệm
A Data Data::operator – (int){
Data temp=*this;
Giam();
return *temp;
}
Phần cài đặt toán tử -- nào sau đây là đúng
B Data Data::operator – (int){
Giam();
Data temp=*this;
return temp;
}
C Data Data::operator – (int){
Data temp=*this;
Giam();
return temp;
}
D Data Data::operator – (int){
Data temp=*this;
temp.Giam();
return this;
}
26
Câu 5: Khi thực thi đoạn chương trình kết quả sẽ là:
class Phanso{
private: int tuso,mauso;
public:
Phanso(int t=0,int m=1){
tuso=t;
mauso=m;
cout<< " ("<<tuso<< "/ "<<mauso<< ") "<<endl;
}
Phanso(const Phanso &x){
tuso=x.tuso;
mauso=x.mauso;
cout<< " ("<<tuso<< "/ "<<mauso<< ") "<<endl;
}
Phanso operator++(int){
Phanso old = *this;
tuso += mauso;
return old;
}
};
Bài tập trắc nghiệm
A. Kết quả in ra là (1/2)(3/2)
B. Chương trình thực thi mà không in
ra kết quả gì
C. Chương trình bị lỗi khi biên dịch
D. Kết quả in ra là (1/2)(1/2) (1/2)
void main(){
Phanso x(1,2);
Phanso y=x++;
};
ĐH CÔNG NGHỆ THÔNG TIN
27
28
ĐÁP ÁN:
Đáp án bài tập trắc nghiệm
Câu Đáp án Giải thích
1 D
2 A
Các toán tử không thể định nghĩa lại:
3 D
ostream: xuất (loại A,B)
istream: nhập (nhập tức dữ liệu phải thay đỗi nên phải dùng tham
chiếu: & ở cả 2 tham số) đáp án D
4 C
b=--a (trừ trước gán sau)
b=a-- (gán trước trừ sau: tức giá trị b phải bằng giá trị a)
5 D
Phanso x(1,2); // Xuất 1 lần do gọi hàm khởi tạo
Phanso old = *this; // Xuất 1 lần do gọi hàm khởi tạo sao chép
Phanso operator++(int) // Xuất 1 lầb do gọi hàm khởi tạo sao chép
. .* :: ?: sizeof
29
ĐÁP ÁN:
Đáp án bài tập trắc nghiệm
Câu Đáp án Giải thích
6 D Hàm ảo phải là hàm thành viên của lớp.
7 A Các khái niệm B,D,C là những khái niệm SAI
8 D Câu lệnh d.BaseA::Print(); đã xác định rõ hàm Print() là của lớp A
9 C
pb là con trỏ lớp cơ bản nên có thể trỏ tới đối tượng là lớp dẫn xuất
nhưng ngược lại thì không.
10 C
Derive d;
d là đối tượng lớp dẫn xuất nên trỉnh tự gọi hàm khởi tạo: lớp cơ
bản gọi trước, lớp dẫn xuất gọi sau.