Microsoft PowerPoint - OOP4-OperatorOverloading_new.ppt

Tài liệu tương tự
Lập trình và ngôn ngữ lập trình

Lớp và đối tượng-các hàm và các lớp friend Lớp và đối tượng-các hàm và các lớp friend Bởi: Thanh Hiền Vũ CÁC HÀM VÀ CÁC LỚP friend Một hàm friend của

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG TIN HỌC ĐẠI CƯƠNG Bài 5. Kiểu dữ liệu và biểu thức trong C Nội dung 1. Các ki

NGÔN NGƯ LÂ P TRIǸH Biên tập bởi: nguyenvanlinh

Những cơ sở của ngôn ngữ C# Những cơ sở của ngôn ngữ C# Bởi: phamvanviet truonglapvy Trong chương này sẽ trình bày về hệ thống kiểu trong C#; phân biệ

Bài 7. Con trỏ Mục tiêu: 1. Luyện tập sử dụng con trỏ và địa chỉ của các biến 2. Sử dụng con trỏ khi thao tác với mảng. Giới hạn: không dùng các thư v

Chương trình dịch

Trường ĐHBK Hà Nội Khoa Điện Bộ môn Điều khiển Tự động Tài liệu hướng dẫn thực hành: KĨ THUẬT LẬP TRÌNH C/C++ Bài 1: Lập trình cơ sở 1 Mục đích bài th

Hàm và lớp template trong Lập trình hướng đối tượng Hàm và lớp template trong Lập trình hướng đối tượng Bởi: unknown Trong phần này, chúng ta tìm hiểu

Copyright vietjack.com Nạp chồng toán tử trong C# Operator Overloading là Nạp chồng toán tử. Bạn có thể tái định

Template and Exception Template and Exception Bởi: Thanh Hiền Vũ TEMPLATE Trong phần này, chúng ta tìm hiểu về một trong các đặc tính còn lại của C++,

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG TIN HỌC ĐẠI CƯƠNG Bài 13. Hàm Nội dung 1. Khái niệm hàm 2. Khai báo và sử dụn

Kế thừa

Microsoft Word - su_dung_sqlite_voi_php.docx

PowerPoint Template

TRƯỜnG ĐẠI HỌC BÁCH KHOA HÀ nội VIỆn CÔnG nghệ THÔnG TIn VÀ TRUYỀn THÔnG TIN HỌC ĐẠI CƯƠNG Bài 10. Các cấu trúc lập trình trong C Nội dung 1. Cấu trúc

Câu lệnh (statement) Câu lệnh (statement) Bởi: Khuyet Danh Trong C# một chỉ dẫn lập trình đầy đủ được gọi là câu lệnh. Chương trình bao gồm nhiều câu

Tìm hiểu ngôn ngữ lập trình Visual Basic Tìm hiểu ngôn ngữ lập trình Visual Basic Bởi: Khuyet Danh Tìm hiểu ngôn ngữ lập trình Visual Basic Tổng quan

Animation, Modules 6 - Hoạt hình, tách file

BÀI TẬP THỰC HÀNH

Microsoft Word - danh-sach-lien-ket-doi-trong-c.docx

Lớp đối tượng trong.net Framework Lớp đối tượng trong.net Framework Bởi: Khuyet Danh Trong chương này chúng ta sẽ tìm hiểu các lớp cơ sở mà.net cung c

Lập trình cấu trúc trong Visual Basic Lập trình cấu trúc trong Visual Basic Bởi: Nguyễn Sơn Học xong chương này, sinh viên phải nắm bắt được các vấn đ

Lớp đối tượng String Lớp đối tượng String Bởi: Khuyet Danh Ngôn ngữ C# hỗ trợ khá đầy đủ các chức năng của kiểu chuỗi mà chúng ta có thể thấy được ở c

Kiểm soát truy suất Kiểm soát truy suất Bởi: Khoa CNTT ĐHSP KT Hưng Yên Khái niệm Bảo mật thực chất là kiểm soát truy xuất [1]. Mục đích của bảo mật m

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG TIN HỌC ĐẠI CƯƠNG Bài 11. Mảng và xâu kí tự Nội dung 1. Mảng 2. Xâu kí tự 2 1

Chiến lược kiểm thử Chiến lược kiểm thử Bởi: Khoa CNTT ĐHSP KT Hưng Yên Các công đoạn kiểm thử Quá trình kiểm thử có thể chia làm các giai đoạn : Kiểm

View, Procedure, Function & Trigger

نظام حماية الخزنة

Chuỗi Chuỗi Bởi: phamvanviet truonglapvy Chuỗi (string) trong C# là một kiểu dựng sẵn như các kiểu int, long, có đầy đủ tính chất mềm dẻo, mạnh mẽ và

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG TIN HỌC ĐẠI CƯƠNG Bài 9. Vào ra dữ liệu trong C Các lệnh vào ra dữ liệu C cun

!#" $ % & % "' ()*+ % &, - %. /0 1 " & ".!% " ;:<5 = : 9HGI7 DKJLG?3 Proxy Pattern M!#" N &OP $ %QP % ' " /!#% P'.!#% "!#" P! "

Cách tạo User và Thiết kế Database Cách tạo User và Thiết kế Database Bởi: Khoa CNTT ĐHSP KT Hưng Yên Cách tạo một User Database Chúng ta có thể tạo m

THƯ VIỆN TRUNG TÂM ĐHQG-HCM PHÒNG PHỤC VỤ ĐỘC GIẢ * I. CỔNG TRA CỨU & TRUY CẬP TÀI LIỆU KHOA HỌC 3 I. MỤC LỤC TRỰC TUYẾN TVTT Tìm lướt:

Microsoft Word - status_code_trong_servlet.docx

Java cơ bản

Hãy chọn phương án đúng CÂU HỎI TRẮC NGHIỆM TIN HỌC 7 HK1 Câu 1: Bảng tính thường được dùng để: a. Tạo bảng điểm của lớp em b. Bảng theo dõi kết quả h

Bài 15: QUẢN LÝ BẢNG TÍNH 15.1 Các khái niệm Ô (cell) là đơn vị cơ sở của bảng tính, mỗi ô có địa chỉ riêng, địa chỉ gồm Chỉ số cột Chỉ số dòng, ví dụ

Kế thừa và đa hình

Microsoft Word - QUI CHE QUAN TRI NOI BO CTY.doc

Hệ điều hành Bài tập tuần 6 1 Quản lý bộ nhớ Bài tập 1 : Xem thông tin bộ nhớ 1. Sử dụng top, ps đọc thông tin về kích thước vùng nhớ của 1 tiến trình

Copyright vietjack.com Chuỗi (String) trong C# Trong C#, bạn có thể sử dụng các chuỗi (string) như là mảng các ký

Quy_che_quan_tri_Cty_KHP.doc

CÔNG TY TNHH THƯƠNG MẠI VÀ DỊCH VỤ NGUYỄN ĐỨC 126 Lê Thanh Nghị - Quận Hai Bà Trưng - Hà Nội Điện Thoai : Fax : Website : www.

Điều khoản sử dụng The Chemours Company, các chi nhánh và công ty con (gọi chung là Chemours ) cung cấp trang web ( Trang web ) này cho bạn theo các đ

Thực hành trên Rose Thực hành trên Rose Bởi: Đoàn Văn Ban Xây dựng biểu đồ thành phần + Tạo lập mới hoặc mở một biểu đồ thành phần đã được tạo lập trư

Microsoft Word - cau-truc-du-lieu-hang-doi.docx

VẠCH MẶT NHÂN CHỨNG GIAN DỐI

Array, Indexer và Collection Array, Indexer và Collection Bởi: phamvanviet truonglapvy Mảng (Array) Mảng là một tập hợp các phần tử có cùng kiểu, được

Bài 4 Tựa bài

Chương 1:

Microsoft Word - [vanbanphapluat.co] qcvn bgtvt

Chủ đề :

OpenStax-CNX module: m Giới thiệu về ngôn ngữ C và môi trường turbo C 3.0 ThS. Nguyễn Văn Linh This work is produced by OpenStax-CNX and licens

Hướng dẫn sử dụng Bếp Từ Bosch PID775N24E Bếp từ 3 bếp nhập khẩu Bosch PID775N24E có DirectControl với truy cập trực tiếp đến 17 cấp độ nấu ăn. 3 khu

Microsoft PowerPoint - L2-Gioi_thieu_WEKA.ppt [Compatibility Mode]

Hệ thống chụp ảnh hướng dẫn sử dụng

quy phạm trang bị điện, chương i.1

Công thái học và quản lý an toàn

Ví dụ về duyệt đồ thị ưu tiên chiều sâu DFS và ứng dụng Đồ thị ví dụ: Nguyễn Hữu Tuân vimaru.edu.vn Hình 1: Đồ thị vô hướng có 8 đỉnh Với đồ thị trên,

Nhúng mã-cách khai báo biến Nhúng mã-cách khai báo biến Bởi: Khoa CNTT ĐHSP KT Hưng Yên Nhúng mã javascript trong trang HTML Bạn có thể nhúng JavaScri

Chương trình dịch

sdfsdfsdfsfsdfd

Cách thức sử dụng phần mềm MT4 của FxPro

Microsoft Word - Bai 7.1.docx

MƯỜI HAI CÁCH TẠO NGHIỆP TỐT Cư Sĩ Lillian Too ĐĐ.Thích Nguyên Tạng Dịch --- o0o --- Nguồn Chuyển sang ebook Người t

Các thanh công cụ Toolbar Các thanh công cụ Toolbar Bởi: Khoa CNTT ĐHSP KT Hưng Yên Origin cung cấp các nút thanh công cụ cho những lệnh menu thường x

PowerPoint Template

Các biến và các kiểu dữ liệu trong JavaScript Các biến và các kiểu dữ liệu trong JavaScript Bởi: Hà Nội Aptech Các biến (Variables) Biến là một tham c

Microsoft Word - kieu_du_lieu_trong_jdbc.docx

Microsoft Word - TNC VIETNAM - Huong dan tong quat PM.doc

Luật kinh doanh bất động sản

TẬP ĐOÀN ĐIỆN LỰC VIỆT NAM TRƯỜNG ĐẠI HỌC ĐIỆN LỰC GIÁO TRÌNH ĐẠI HỌC BẢO VỆ RƠLE TRONG HỆ THỐNG ĐIỆN Tài liệu tham khảo nội bộ dùng trong Khoa Hệ thố

MỞ ĐẦU

Nhập môn Công Nghệ Thông Tin 1

Tài chính, tín dụng, ngân hàng và lưu thông tiền tệ trong thời kỳ quá độ lên chủ nghĩa xã hội ở Việt Nam Tài chính, tín dụng, ngân hàng và lưu thông t

Bài thực hành 6 trang 106 SGK Tin học 10

(Tái bản lần thứ hai)

INTERSCAN VIRUSWALL V

Microsoft Word - server_response_trong_servlet.docx

Microsoft Word - co_ban_ve_jquery.docx

Stored Procedures Stored Procedures Bởi: Khoa CNTT ĐHSP KT Hưng Yên Trong những bài học trước đây khi dùng Query Analyzer chúng ta có thể đặt tên và s

Microsoft Word - bo_tien_xu_ly_trong_c.docx

Chương II - KIẾN TRÚC HỆ ĐIỀU HÀNH

Slide 1

Lương Sĩ Hằng Tha Thứ Và Thương Yêu

LIÊN MINH ĐẢNG CỘNG HOÀ Đảng của nhân dân nhằm thiết lập lại nền dân chủ HIẾN CHƯƠNG THÀNH LẬP Được thông qua trong hội nghị thành lập Liên minh Đảng

IPSec IPSec Bởi: Phạm Nguyễn Bảo Nguyên Chúng ta đã biết khi ta sao chép dữ liệu giữa 2 máy hoặc thông qua mạng VPN để nâng cao chế độ bảo mật người q

Microsoft Word - action_trong_jsp.docx

LỜI TỰA Sau khi cuốn sách Kinh nghiệm thành công của ông chủ nhỏ đầu tiên của tôi được phát hành, không ngờ chỉ trong vòng nửa năm đã có tới hơn một t

Microsoft Word - IP Law 2005 (Vietnamese).doc

(Tái bản lần thứ hai)

ĐIỂM THI KHỐI A ĐẠI HỌC BÁCH KHOA ĐÀ NẴNG ầ ươ ữ ặ ố ả ườ ườ ườ ễ ướ ườ ườ ầ ườ ễ ữ ấ ồ ấ ứ ấ ố ấ ễ ấ ễ ả ấ ễ ướ ấ ễ ấ ễ ấ ễ ấ ễ ấ ấ ồ ố ấ ạ ấ ầ ấ ầ ấ

Huong dan su dung phan mem Quan ly chat luong cong trinh GXD

daithuavoluongnghiakinh

Cúc cu

LỜI GIỚI THIỆU Chia sẽ ebook : Tham gia cộng đồng chia sẽ sách : Fanpage : C

Microsoft Word - TCVN

Bản ghi:

CHƯƠNG 4: ĐA NĂNG HOÁ TOÁN N TỬT (OPERATOR OVERLOADING) Khoa Công Nghệ Thông Tin và Truyền Thông Đại học Bách khoa Đại học Đà Nẵng Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 1 Đa năng hoá hàm. Đa năng hoá toán tử. Nội dung Giới hạn của đa năng hoá toán tử Chuyển đổi kiểu. Đa năng hoá toán tử xuất (<<) nhập (>>) Đa năng hoá toán tử [], toán tử () Khởi tạo ngầm định - Gán ngầm định. Đa năng hoá toán tử ++ và -- Đa năng hoá new và delete Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 2

Đa năng hoá hàm Định nghĩa các hàm cùng tên Đối số phải khác nhau: Số lượng Thứ tự Kiểu class Time { //... long GetTime (void); // số giây tính từ nửa đêm void GetTime (int &hours, int &minutes, int &seconds); void main() { int h, m, s; long t = GetTime(); // Gọi hàm??? GetTime(h, m, s); // Gọi hàm??? Có thể dùng đối số mặc định. Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 3 Đa năng hoá toán tử Định nghĩa các phép toán trên đối tượng. Các phép toán có thể tái định nghĩa: Đơn hạng + new - delete *! ~ & ++ -- () -> ->* + - * / % & ^ << >> Nhị hạng = += -= /= %= &= = ^= <<= >>= ==!= < > <= >= && [] (), Các phép toán không thể tái định nghĩa:..* ::?: sizeof Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 4

Giới hạn của đa năng hoá toán tử toán tử gọi hàm () - là một toán tử nhiều ngôi. Thứ tự ưutiêncủa một toán tử không thể được thay đổi bởi đa năng hóa. Tính kết hợp của một toán tử không thể được thay đổi bởi đa năng hóa. Các tham số mặc định không thể sử dụng với một toán tử đanăng hóa. Không thể thay đổi số các toán hạng mà một toán tử yêu cầu. Không thể thay đổi ý nghĩa của một toán tử làm việc trêncáckiểu cósẵn. Không thể dùng đối số mặc định. Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 5 Đa năng hoá toán tử Khai báo và định nghĩa toán tử thực chất không khác với việc khai báo và định nghĩa nghĩa một loại hàm bất kỳ nào khác sử dụng tên hàm là "operator@" cho toán tử "@" để overload phép "+", ta dùng tên hàm "operator+" Số lượng tham số tại khai báo phụ thuộc hai yếu tố: Toán tử là toán tử đơnhay đôi Toán tử được khai báo là hàm toàn cục hay phương thức của lớp aa@bb aa.operator@(bb) hoặc operator@(aa,bb) @aa aa.operator@( ) hoặc operator@(aa) aa@ aa.operator@(int) hoặc operator@(aa,int) Là phương thức của lớp Là hàm toàn cục Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 6

Đa năng hoá toán tử Ví dụ: Sử dụng toán tử "+" để cộng hai đối tượng MyNumber và trả về kết quả là một MyNumber Ta có thể khai báo hàm toàn cục sau const MyNumber operator+(const MyNumber& num1, const MyNumber& num2); "x+y" sẽ đượchiểulà "operator+(x,y)" dùng từ khoá const để đảm bảo các toán hạng gốc không bị thay đổi Hoặc khai báo toán tử dưới dạng thành viên của MyNumber: const MyNumber operator+(const MyNumber& num); MyNumber x(5); MyNumber y(10);... z = x + y; đối tượng chủ của phương thức được hiểu làtoánhạng thứ nhất của toán tử. "x+y" sẽ đượchiểu là "x.operator+(y)" Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 7 Đa năng hoá toán tử (tt) Bằng hàm thành viên: Khi đa năng hóa (), [], -> hoặc =, hàm đa năng hóa toán tử phải được khai báo như một thành viên lớp class Point { Point (int x, int y) { Point::x = x; Point::y = y; Point operator + (Point &p) { return Point(x + p.x,y + p.y); Point operator - (Point &p) { return Point(x - p.x, y - p.y); private: int x, y; void main() { Point p1(10,20), p2(10,20); Point p3 = p1 + p2; Point p4 = p1 - p2; Point p5 = p3.operator + (p4); Point p6 = p3.operator (p4); Có 1 tham số (Nếu làtoántử hai ngôi) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 8

Đa năng hoá toán tử (tt) Toán tử là hàm toàn cục Quay lại với vídụ về phép cộng cho MyNumber, ta có thể khai báo hàm định nghĩa phép cộng tại mức toàn cục: const MyNumber operator+(const MyNumber& num1, const MyNumber& num2); Khi đó, ta có thể định nghĩa toán tử đónhư sau: const MyNumber operator+(const MyNumber& num1,const MyNumber& num2) { MyNumber result(num1.value + num2.value); return result; Truy nhập cácthànhviênprivate value Ởđây có vấn đề. Giải pháp: dùng hàm friend friend cho phép một lớp cấp quyền truynhập tới các phần nội bộ của lớp đó cho một số cấu trúc được chọn Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 9 Đa năng hoá toán tử (tt) Để khai báo một hàm là friend của một lớp, ta phải khai báo hàm đó bên trong khai báo lớp vàđặt từ khoá friend lên đầu khai báo. class MyNumber { MyNumber(int value = 0); ~MyNumber();... friend const MyNumber operator+(const MyNumber& num1,const MyNumber& num2);... Lưu ý: tuy khai báo của hàm friend được đặt trong khai báo lớp vàhàmđó có quyền truynhập ngang với cácphương thức của lớp, hàm đó không phải phương thức của lớp Không cần thêmsửa đổi gìchođịnh nghĩa của hàm đã được khai báo là friend. Định nghĩa trước của phép cộng vẫn giữ nguyên const MyNumber operator+(const MyNumber& num1,const MyNumber& num2) { MyNumber result(num1.value + num2.value); return result; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 10

Đa năng hoá toán tử (tt) Tại sao dùng toán tử toàn cục? Đối với toántửđược khai báo là phương thức của lớp, đối tượng chủ (xác định bởi con trỏ this) luôn được hiểu làtoánhạng đầu tiên (trái nhất) của phép toán. Nếu muốn dùng cách này, ta phải được quyền bổ sung phương thức vào định nghĩa của lớp/kiểu của toán hạng trái Không phải lúc nào cũng có thể overload toán tử bằng phương thức phép cộng giữa MyNumber và int cần cả hai cách MyNumber + int và int + MyNumber cout << obj; không thể sửa định nghĩa kiểu int hay kiểu của cout lựa chọn duy nhất: overload toán tử bằng hàm toàn cục Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 11 Đa năng hoá toán tử (tt) Bằng hàm toàn cục: nếu toán hạng cực trái của toán tử là đối tượng thuộc lớp khác hoặc thuộc kiểu dữ liệu có sẵn thường khai báo friend class Point { Point (int x, int y) { Point::x = x; Point::y = y; friend Point operator + (Point &p, Point &q) {return Point(p.x + q.x,p.y + q.y); friend Point operator - (Point &p, Point &q) {return Point(p.x - q.x,p.y - q.y); private: Có 2 tham số int x, y; (Nếu làtoántử hai ngôi) void main() { Point p1(10,20), p2(10,20); Point p3 = p1 + p2; Point p4 = p1 - p2; Point p5 =operator + (p3, p4); Point p6 = operator (p3, p4); Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 12

Đa năng hoá toán tử (tt) Cải tiến lớp tập hợp (Set): #include <iostream.h> const maxcard = 100; enum Bool {false, true class Set { Set(void) { card = 0; friend Bool operator & (const int, Set&);// thanh vien? friend Bool operator == (Set&, Set&); // bang? friend Bool operator!= (Set&, Set&); // khong bang? friend Set operator * (Set&, Set&); // giao friend Set operator + (Set&, Set&); // hop //... void AddElem(const int elem); void Copy (Set &set); void Print (void); private: int elems[maxcard]; int card; // Định nghĩa các toán tử.. int main (void) { Set s1, s2, s3; s1.addelem(10); s1.addelem(20); s1.addelem(30); s1.addelem(40); s2.addelem(30); s2.addelem(50); s2.addelem(10); s2.addelem(60); cout << "s1 = "; s1.print(); cout << "s2 = "; s2.print(); if (20 & s1) cout << "20 thuoc s1\n"; cout << "s1 giao s2 = "; (s1 * s2).print(); cout << "s1 hop s2 = "; (s1 + s2).print(); if (s1!= s2) cout << "s1 /= s2\n"; return 0; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 13 Chuyển kiểu Muốn thực hiện các phép cộng: void main() { Point p1(10,20), p2(30,40), p3, p4, p5; p3 = p1 + p2; p4 = p1 + 5; p5 = 5 + p1; Có thể định nghĩa thêm 2 toán tử: class Point { //... friend Point operator + (Point, Point); friend Point operator + (int, Point); friend Point operator + (Point, int); Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 14

Chuyển kiểu (tt) Chuyển đổi kiểu: ngôn ngữ định nghĩa sẵn. void main() { Point p1(10,20), p2(30,40), p3, p4, p5; p3 = p1 + p2; p4 = p1 + 5; // tương đương p1 + Point(5) p5 = 5 + p1; // tương đương Point(5) + p1 Định nghĩa phép chuyển đổi kiểu class Point { //... Point (int x) { Point::x = Point::y = x; friend Point operator + (Point, Point); Chuyển kiểu 5 Point(5) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 15 Chuyển kiểu (tt) Một toán tử chuyển đổi kiểu cóthểđượcsử dụng để chuyển đổi một đối tượng của một lớp thành đối tượng của một lớp khác hoặc thành một đối tượng của một kiểu cósẵn. Toán tử chuyển đổi kiểu như thế phải là hàm thành viên không tĩnh và không là hàm friend. Prototype của hàm thành viên này có cú pháp: operator <data type> (); Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 16

Ví dụ: class Number { private: float Data; Number(float F=0.0) { Data=F; operator float() { return Data; operator int() { return (int)data; Chuyển kiểu (tt) int main() { Number N1(9.7), N2(2.6); float X=(float)N1; //Gọi operator float() cout<<x<<endl; int Y=(int)N2; //Gọi operator int() cout<<y<<endl; return 0; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 17 Đa năng hoá toán tử xuất << prototype như thế nào? xét ví dụ: cout << num; // num là đối tượng thuộc lớp MyNumber Toán hạng trái cout thuộc lớp ostream, không thể sửa định nghĩa lớp này nên ta overload bằng hàm toàn cục Tham số thứ nhất : tham chiếu tới ostream Tham số thứ hai : kiểu MyNumber, const (do không có lý do gì để sửa đối tượng được in ra) giá trị trả về: tham chiếu tới ostream (để thực hiện được cout << num1 << num2;) Kết luận: ostream& operator<<(ostream& os, const MyNumber& num) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 18

Đa năng hoá toán tử xuất << Khaibáotoántửđược overload là friend của lớp MyNumber class MyNumber { MyNumber(int value = 0); ~MyNumber();... friend ostream& operator<<( ostream& os, const MyNumber& num);... Định nghĩa toán tử ostream& operator<<(ostream& os, const MyNumber& num) { os << num.value; // Use version of insertion operator defined for int return os; // Return a reference to the modified stream Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 19 Đa năng hoá toán tử nhập >> prototype như thế nào? xét ví dụ: cin << num; // num là đối tượng thuộc lớp MyNumber Toán hạng trái cin thuộc lớp istream, không thể sửa định nghĩa lớp này nên ta overload bằng hàm toàn cục Tham số thứ nhất : tham chiếu tới istream Tham số thứ hai : kiểu MyNumber, giá trị trả về: tham chiếu tới ostream (để thực hiện được cin >> num1 >> num2;) Kết luận: istream& operator>>(istream& is, MyNumber& num) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 20

Đa năng hoá toán tử xuất >> Khaibáotoántửđược overload là friend của lớp MyNumber class MyNumber { MyNumber(int value = 0); ~MyNumber();... friend istream& operator>>( istream& is, MyNumber& num);... Định nghĩa toán tử istream& operator>>(istream& is, MyNumber& num) { cout<< Nhap so: ; is >> num.value; return is; // Return a reference to the modified stream Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 21 Đa năng hoá toán tử [ ] Thông thường để xuất ragiátrị của 1 phần tử tại vị trí cho trước trong đối tượng. Định nghĩa là hàm thành viên. Để hàm toán tử [] có thể đặt ở bên trái của phép gán thì hàm phải trả về là một tham chiếu class StringVec { StringVec (const int dim); ~StringVec (); char* operator [] (int); int add(char* ); //.. private: char **elems; // cac phan tu int dim; // kich thuoc cua vecto int used; // vi tri hien tai char* StringVec::operator [] (int i) { if ( i>=0 && i<used) return elems[i]; return ; void main() { StringVec sv1(100); sv1.add( PTPhi );sv1.add( BQThai ); sv1.add( LVLam ); sv1.add( NCHuy ); cout<< sv1[2]<<endl; cout<<sv1[0]; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 22

Đa năng hoá toán tử () Định nghĩa là hàm thành viên. class Matrix { Matrix (const short rows, const short cols); ~Matrix (void) {delete elems; double& operator () (const short row, const short col); friend ostream& operator << (ostream&, Matrix&); friend Matrix operator + (Matrix&, Matrix&); friend Matrix operator - (Matrix&, Matrix&); friend Matrix operator * (Matrix&, Matrix&); private: const short rows; // số hàng const short cols; // số cột double *elems; // các phần tử double& Matrix::operator () (const short row, const short col) { static double dummy = 0.0; return (row >= 1 && row <= rows && col >= 1 && col <= cols)? elems[(row - 1)*cols + (col - 1)] : dummy; void main() { Matrix m(3,2); m(1,1) = 10; m(1,2) = 20; m(2,1) = 30; m(2,2) = 40; m(3,1) = 50; m(3,2) = 60; cout<<m<<endl; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 23 Khởi tạo ngầm định Được định nghĩa sẵn trong ngôn ngữ: VD: Point p1(10,20); Point p2 = p1; Sẽ gây ra lỗi (kết quả SAI) khi bên trong đối tượng có thành phần dữ liệu là con trỏ. VD: Matrix m(5,6); Matrix n = m; Lỗi sẽ xảy ra do khởi tạo ngầm bằng cách gán tương ứng từng thành phần. Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 24

Khởi tạo ngầm định (tt) Khi lớp cóthành phần dữ liệu con trỏ, phải định nghĩa hàm xây dựng sao chép class Point { int x, y; Point (int =0; int =0 ); // Khong can thiet DN Point (const Point& p) { x= p.x; y = p.y; //.. // class Matrix { //. Matrix(const Matrix&); Matrix::Matrix (const Matrix &m) : rows(m.rows), cols(m.cols) { int n = rows * cols; elems = new double[n]; // cùng kích thước for (register i = 0; i < n; ++i) // sao chép phần tử elems[i] = m.elems[i]; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 25 Gán ngầm định Được định nghĩasẵn trong ngôn ngữ: Gán tương ứng từng thành phần. Đúng khi đối tượng không có dữ liệu con trỏ. VD: Point p1(10,20); Point p2; p2 = p1; Khi thành phần dữ liệu cócon trỏ, bắt buộc phải định nghĩa phép gán = cho lớp. Hàm thành viên class Matrix { //. Matrix& operator = (const Matrix &m) { if (rows == m.rows && cols == m.cols) { // phải khớp int n = rows * cols; for (register i = 0; i < n; ++i) // sao chép các phần tử elems[i] = m.elems[i]; return *this; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 26

Phép gán "=" Một trong những toán tử hay được overload nhất Cho phép gán cho đối tượng này một giátrị dựa trênmột đối tượng khác Copy constructor cũng thực hiện việc tương tự, cho nên, định nghĩa toántử gán gần như giống hệt định nghĩa của copy constructor Ta có thể khai báo phép gán cho lớp MyNumber như sau: const MyNumber& operator=(const MyNumber& num); Phép gán nên luôn luôn trả về một tham chiếu tới đối tượng đích (đối tượng được gántrị cho) Tham chiếu được trả về phải làconst để tránh trường hợp a bị thay đổi bằng lệnh "(a = b) = c;" (lệnh đó không tương thích với định nghĩa gốc của phép gán) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 27 Phép gán "=" const MyNumber& MyNumber::operator=(const MyNumber& num) { if (this!= &num) { this->value = num.value; return *this; Định nghĩa trêncóthể dùng cho phép gán Lệnh if dùng để ngăn chặn cácvấn để có thể nảy sinhkhimột đối tượng được gán cho chính nó (thí dụ khi sử dụng bộ nhớ động để lưu trữ các thành viên) Ngay cả khi gán một đối tượng cho chính nó là an toàn, lệnh if trên đảm bảo không thực hiện các công việc thừa khi gán Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 28

Phép gán "=" Khi nói về copy constructor, ta đã biết rằng C++ luôn cung cấp một copy constructor mặc định, nhưng nó chỉ thực hiện sao chép đơn giản (sao chép nông) Đối với phép gán cũng vậy Vậy, ta chỉ cần định nghĩa lại phép gán nếu: Ta cần thực hiện phép gán giữa cácđối tượng Phép gán nông (memberwise assignment) không đủ dùng vì ta cần sao chép sâu - chẳng hạn sử dụng bộ nhớ động Khi sao chép đòi hỏi cả tính toán-chẳng hạn gán một số hiệu cógiátrị duy nhất hoặc tăng số đếm Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 29 Đa năng hoá toán tử ++ & -- Toán tử ++ (hoặc toán tử --) có 2 loại: Tiền tố: ++n Hậu tố: n++ (Hàm toán tử ởdạng hậu tố có thêm đối số giả kiểu int) Phép tăng ++ giá trị trả về tăng trước ++num trả về tham chiếu (MyNumber &) giá trị trái - lvalue (có thể được gán trị) tăng sau num++ trả về giá trị (giá trị cũ trước khităng) trả về đốitượng tạm thời chứa giátrị cũ. giá trị phải - rvalue (không thể làm đích của phép gán) prototype tăng trước: MyNumber& MyNumber::operator++() tăng sau: const MyNumber MyNumber::operator++(int) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 30

Đa năng hoá toán tử ++ & -- Nhớ lại rằng phép tăng trước tăng giá trị trước khitrả kết quả, trong khi phép tăng sau trả lại giátrị trước khităng Ta định nghĩa từng phiên bản của phép tăng như sau: MyNumber& MyNumber::operator++() { // Prefix this->value++; // Increment value return *this; // Return current MyNumber const MyNumber MyNumber::operator++(int) { // Postfix MyNumber before(this->value); // Create temporary MyNumber // with current value this->value++; // Increment value return before; // Return MyNumber before increment before là một đối tượng địa phương của phương thức và sẽ chấm dứt tồn tại khi lời gọi hàm kết thúc Khi đó, tham chiếu tới nótrở thành bất hợp lệ Không thể trả về tham chiếu Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 31 Tham số và kiểu trả về Cũng như khi overload các hàm khác, khi overload một toán tử, ta cũng có nhiều lựa chọn về việc truyền tham số và kiểu trả về chỉ có hạn chế rằng ít nhất một trong các tham số phải thuộc kiểu người dùng tự định nghĩa Ởđây, ta có một số lời khuyên về các lựa chọn Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 32

Tham số và kiểu trả về Các toán hạng: Nên sử dụng tham chiếu mỗi khicóthể (đặc biệt làkhi làm việc với các đối tượng lớn) Luônluônsử dụng tham số là hằng tham chiếu khiđối số sẽ không bị sửa đổi bool String::operator==(const String &right) const Đối với cáctoántử là phương thức, điều đó cónghĩa tanên khai báo toán tử là hằng thành viên nếu toán hạng đầu tiên sẽ không bị sửa đổi Phần lớn các toán tử (tính toán và so sánh) không sửa đổi các toán hạng của nó, do đó tasẽ rất hay dùng đến hằng tham chiếu Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 33 Tham số và kiểu trả về Giá trị trả về khôngcóhạn chế về kiểu trả về đốivới toán tử được overload, nhưng nên cố gắng tuân theo tinh thần của các cài đặt cósẵn của toán tử Ví dụ, các phép so sánh (==,!= ) thường trả về giá trị kiểu bool, nên các phiên bản overload cũng nên trả về bool là tham chiếu (tới đối tượng kết quả hoặc một trong các toán hạng) hay một vùng lưu trữ mới Hằng hay không phải hằng Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 34

Tham số và kiểu trả về Giá trị trả về Các toán tử sinh một giátrị mới cần cókết quả trả về là một giátrị (thay vì tham chiếu), và là const (để đảm bảo kết quảđókhôngthể bị sửa đổi như một l-value) Hầu hết các phép toán số học đều sinhgiátrị mới ta đã thấy, các phép tăng sau, giảm sau tuân theo hướng dẫn trên Các toán tử trả về một tham chiếu tới đối tượng ban đầu (đã bị sửa đổi), chẳng hạn phép gán và phép tăng trước, nên trả về tham chiếu khôngphải làhằng để kết quả có thể đượctiếp tục sửa đổi tại cácthaotáctiếp theo const MyNumber MyNumber::operator+(const MyNumber& right) const MyNumber& MyNumber::operator+=(const MyNumber& right) Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 35 Tham số và kiểu trả về Xem lại cáchtađãdùng để trả về kết quả của toán tử: const MyNumber MyNumber::operator+(const MyNumber& num) { MyNumber result(this->value + num.value); return result; 3. Gọi destructor để huỷ đối tượng result Cách trên không sai, nhưng C++ cung cấp một cách hiệu quả hơn const MyNumber MyNumber::operator+(const MyNumber& num) { return MyNumber(this->value + num.value); 1. Gọi constructor để tạo đối tượng result 2. Gọi copy-constructor để tạo bản sao dành cho giá trị trả về khi hàm thoát Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 36

Tham số và kiểu trả về return MyNumber(this->value + num.value); Cú pháp của vídụ trước tạo một đối tượng tạm thời (temporary object) Khi trình biên dịch gặp đoạn mã này, nó hiểu đối tượng được tạo chỉ nhằm mục đích làm giá trị trả về, nên nó tạo thẳng một đối tượng bên ngoài (để trả về) - bỏ qua việc tạo vàhuỷđốitượng bên trong lời gọi hàm Vậy, chỉ có một lời gọi duy nhất đến constructor của MyNumber (không phải copy-constructor) thay vì dãy lời gọi trước Quá trình này được gọi làtối ưu hoá giá trị trả về Ghi nhớ rằng quá trình này không chỉ áp dụng được đối với các toán tử. Ta nên sử dụng mỗi khitạo một đối tượng chỉ đểtrả về Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 37 Đa năng hoá new & delete Hàm new và delete mặc định của ngôn ngữ: Nếu đối tượng kích thước nhỏ, có thể sẽ gây ra quá nhiều khối nhỏ => chậm. Không đáng kể khi đối tượng có kích thước lớn. => Toán tử new và delete ít được táiđịnh nghĩa. Định nghĩa theo dạng hàm thành viên: class Point { //... void* operator new (size_t bytes); void operator delete (void *ptr, size_t bytes); private: int xval, yval; void main() { Point *p = new Point(10,20); Point *ds = new Point[30]; // delete p; delete []ds; Khoa Công Nghệ Thông Tin - Đại Học Bách khoa Đà Nẵng 38