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

Tài liệu tương tự
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

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++,

Lập trình và ngôn ngữ lập trình

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

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

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

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

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ệ

Kế thừa

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

Chương trình dịch

Microsoft Word - bo_tien_xu_ly_trong_c.docx

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

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

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

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,

Kế thừa và đa hì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ý

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 đ

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

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

Microsoft Word - server_response_trong_servlet.docx

1

Chương 1:

Microsoft PowerPoint - OOP4-OperatorOverloading_new.ppt

Microsoft Word - su_dung_sqlite_voi_php.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

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

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

Danh sách tuyến tính kiểu hàng đợi Danh sách tuyến tính kiểu hàng đợi Bởi: Khoa CNTT ĐHSP KT Hưng Yên ĐỊNH NGHĨA Hàng đợi là một vật chứa (container)

BẢO MẬT HỆ THỐNG THÔNG TIN

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

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 - Bai 7.1.docx

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

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à

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

Xử lý ngoại lệ

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

Microsoft Word - session_tracking_trong_servlet.docx

Bài tập thực hành Chuyên đề 1 CNPM - Java Khoa CNTT- Trường ĐH Công nghệ TP.HCM Lab 01: LẬP TRÌNH JAVA CƠ BẢN VỚI NET BEANS A. MỤC TIÊU: Hướng dẫn tải

Microsoft Word - co_ban_ve_jquery.docx

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

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

Kiểu dữ liệu văn bản Kiểu dữ liệu văn bản Bởi: PGS. TS. NGƯT Phạm Văn Huấn Ngoài những dữ liệu số như các số nguyên, số thực, máy tính còn có thể lưu

PowerPoint Template

Microsoft Word - action_trong_jsp.docx

Microsoft Word - status_code_trong_servlet.docx

Slide 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

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

sdfsdfsdfsfsdfd

HỘI THI TIN HỌC TRẺ TỈNH AN GIANG ĐỀ CHÍNH THỨC ĐỀ THI LÝ THUYẾT BẢNG A - KHỐI TIỂU HỌC Khóa ngày: Thời gian : 20 phút (không kể thời gian

9-KiemThu

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. Tệp tin Nội dung 1. Khái niệm cơ bản 2. Các thao tá

Java cơ bản

Chương 4 : Sử dụng Hàm(Function) Chương 4 : Sử dụng Hàm(Function) Bởi: Khoa CNTT ĐHSP KT Hưng Yên Hàm (Function) được xem như là những công thức định

I. MSWLogo là gì. Giới thiệu. Là một ngôn ngữ lập trình được thiết kế và phát triển bởi Seymour Papert, Daniel Bobrow và Wallace Feurzeig. Trong chươn

Microsoft Word - custom_component_trong_android.docx

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

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

Slide 1

In trực tuyến 4.0

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ụ

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

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

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

Computer Architecture

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

HƯỚNG DẪN CHUYỂN KHOẢN VÀ THANH TOÁN HÓA ĐƠN

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

Microsoft Word - xu_ly_cookie_trong_servlet.docx

Microsoft Word - kieu_du_lieu_trong_jdbc.docx

Microsoft Word - Huong dan su dung Mailchimp.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 - google_map_trong_android.docx

mySQL - Part 1 - Installation

View, Procedure, Function & Trigger

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

UART0

Microsoft Word - activity_trong_android.docx

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.

HƯỚNG DẪN SỬ DỤNG DỊCH VỤ STORAGE.COM.VN

KIỂM TOÁN NHÀ NƯỚC CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc lập - Tự do - Hạnh phúc Số: 1173/QĐ-KTNN Hà Nội, ngày 27 tháng 7 nă

THƯ VIỆN PHÁP LUẬT

Cây nhị phân tìm kiếm Cây nhị phân tìm kiếm Bởi: Trần Hạnh Nhi CÂY NHỊ PHÂN TÌM KIẾM Định nghĩa: Cây nhị phân tìm kiếm (CNPTK) là cây nhị phân trong đ

QUỐC HỘI CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc lập - Tự do - Hạnh phúc Nghị quyết số: 41/2017/QH14 Hà Nội, ngày 20 tháng 6 n

CÔNG BÁO/Số /Ngày PHẦN VĂN BẢN QUY PHẠM PHÁP LUẬT CHÍNH PHỦ CHÍNH PHỦ Số: 92/2011/NĐ-CP CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM Độc l

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:

Hướng dẫn sử dụng SSI Pro Trading dành cho MG

Chủ đề :

PowerPoint Template

Slide 1

Quyết định số 218/2000/QĐ-BTC ngày 29/12/2000

TCVN 11391:2016 MỤC LỤC 1 Phạm vi áp dụng Tài liệu viện dẫn Thuật ngữ, định nghĩa và các từ viết tắt Thuật ngữ và định nghĩa...

Microsoft Word - mot_so_tool_trong_android.docx

Microsoft PowerPoint - Chuong_06.ppt

Tài liệu Hướng dẫn sử dụng

Bản ghi:

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 một lớp được định nghĩa bên ngoài phạm vi của lớp đó, lúc này có quyền truy cập đến các thành viên private hoặc protected của một lớp. Một hàm hay toàn bộ lớp có thể được khai báo là một friend của lớp khác. Để khai báo một hàm là một friend của một lớp, đứng trước prototype của hàm trong định nghĩa lớp với từ khóa friend. như sau: friend <function-declarator>; Để khai báo một lớp là friend của lớp khác như sau: friend <class-name>; Ví dụ 3.16: Chương trình sau minh họa khai báo và sử dụng hàm friend. CT3_16.CPP 1: #include <iostream.h>2: 3: class Count4: {5: friend void SetX(Count &, int); //Khai báo friend6: public:7: Count()//Constructor8: {9: X = 0;10: }11: void Print() const //Xuất12: {13: cout << X << endl;14: }15: private:16: int X;17: };18:19: //Có thể thay đổi dữ liệu private của lớp Count vì20: //SetX() khai báo là một hàm friend của lớp Count21: void SetX(Count &C, int Val)22: {23: C.X = Val; //Hợp lệ: SetX() là một hàm friend của lớp Count24: }25: 26: int main()27: {28: Count Object;29: 30: cout << "Object.X after instantiation: ";31: Object.Print();32: cout << "Object.X after call to SetX friend function: ";33: SetX(Object, 8); //Thiết lập X với một friend34: Object.Print();35: return 0;36: } 1/8

Chúng ta chạy ví dụ 3.16, kết quả ở hình 3.17 Hình 3.17: Kết quả của ví dụ 3.16 Có thể chỉ định các hàm được đa năng hóa là các friend của lớp. Mỗi hàm được đa năng hóa phải được khai báo tường minh trong định nghĩa lớp như là một friend của lớp. CON TRỎ THIS Khi một hàm thành viên tham chiếu thành viên khác của lớp cho đối tượng cụ thể của lớp đó, làm thế nào C++ bảo đảm rằng đối tượng thích hợp được tham chiếu? Câu trả lời là mỗi đối tượng duy trì một con trỏ trỏ tới chính nó gọi là con trỏ this Đó là một tham số ẩn trong tất cả các tham chiếu tới các thành viên bên trong đối tượng đó. Con trỏ this cũng có thể được sử dụng tường minh. Mỗi đối tượng có thể xác định địa chỉ của chính mình bằng cách sử dụng từ khóa this. Con trỏ this được sử dụng để tham chiếu cả các thành viên dữ liệu và hàm thành viên của một đối tượng. Kiểu của con trỏ this phụ thuộc vào kiểu của đối tượng và trong hàm thành viên con trỏ this được sử dụng là khai báo const. Chẳng hạn, một hàm thành viên không hằng của lớp Employee con trỏ this có kiểu là: Employee * const //Con trỏ hằng trỏ tới đối tượng Employee Đối với một hàm thành viên hằng của lớp Employee con trỏ this có kiểu là: const Employee * const //Con trỏ hằng trỏ tới đối tượng Employee mà là một hằng Ví dụ 3.17: Chương trình sau minh họa sử dụng tường minh của con trỏ this để cho phép một hàm thành viên của lớp Test in dữ liệu X của một đối tượng Test. CT3_17.CPP 1: #include <iostream.h>2: 3: class Test4: {5: public:6: Test(int = 0); // Constructor mặc định7: void Print() const;8: private:9: int X;10: };11:12: Test::Test(int A)13: {14: X = A;15: }16:17: void Test::Print() const18: {19: cout << " X 2/8

= " << X << endl20: << " this->x = " << this->x << endl21: << "(*this).x = " << (*this).x << endl;22: }23:24: int main()25: {26: Test A(12);27: 28: A.Print();29: return 0;30: } Chúng ta chạy ví dụ 3.17, kết quả ở hình 3.18 Hình 3.18: Kết quả của ví dụ 3.17 Một cách khác sử dụng con trỏ this là cho phép móc vào nhau các lời gọi hàm thành viên. Ví dụ 3.18: Chương trình sau minh họa trả về một tham chiếu tới một đối tượng Time để cho phép các lời gọi hàm thành viên của lớp Time được móc nối vào nhau. CT3_18.CPP 1: #include <iostream.h>2:3: class Time4: {5: public:6: Time(int = 0, int = 0, int = 0); // Constructor mặc định7: // Các hàm set8: Time &SetTime(int, int, int); // Thiết lập Hour, Minute va Second9: Time &SetHour(int); // Thiết lập Hour10: Time &SetMinute(int); // Thiết lập Minute11: Time &SetSecond(int); // Thiết lập Second12: // Các hàm get13: int GetHour() const; // Trả về Hour14: int GetMinute() const; // Trả về Minute15: int GetSecond() const; // Trả về Second16: // Các hàm in17: void PrintMilitary() const; // In thời gian theo dạng giờ quân đội18: void PrintStandard() const; // In thời gian theo dạng giờ chuẩn19: private:20: int Hour; // 0-2321: int Minute; // 0-5922: int Second; // 0-5923: };24:25: // Constructor khởi động dữ liệu private26: // Gọi hàm thành viên SetTime() để thiết lập các biến27: // Các giá trị mặc định là 028: Time::Time(int Hr, int Min, int Sec)29: {30: SetTime(Hr, Min, Sec);31: }32:33: // Thiết lập các giá trị của Hour, Minute, và Second34: Time &Time::SetTime(int H, int M, int S)35: {36: Hour = (H >= 0 && H < 24)? H : 0;37: Minute = (M >= 0 && M < 60)? M : 0;38: Second = (S >= 0 && S < 60)? S : 0;39: return *this; // Cho phép móc nối40: }41:42: // Thiết lập giá trị của Hour43: Time &Time::SetHour(int H)44: {45: 3/8

Hour = (H >= 0 && H < 24)? H : 0;46: return *this; // Cho phép móc nối47: }48: 49: // Thiết lập giá trị của Minute50: Time &Time::SetMinute(int M)51: {52: Minute = (M >= 0 && M < 60)? M : 0;53: return *this; // Cho phép móc nối54: }55: 56: // Thiết lập giá trị của Second57: Time &Time::SetSecond(int S)58: {59: Second = (S >= 0 && S < 60)? S : 0;60: return *this; // Cho phép móc nối61: }62:63: // Lấy giá trị của Hour64: int Time::GetHour() const65: {66: return Hour;67: }68:69: // Lấy giá trị của Minute70: int Time::GetMinute() const71: {72: return Minute;73: }74:75: // Lấy giá trị của Second76: int Time::GetSecond() const77: {78: return Second;79: }80:81: // Hiển thị thời gian dạng giờ quân đội: HH:MM:SS82: void Time::PrintMilitary() const83: {84: cout << (Hour < 10? "0" : "") << Hour << ":"85: << (Minute < 10? "0" : "") << Minute << ":"86: << (Second < 10? "0" : "") << Second;87: }88:89: // Hiển thị thời gian dạng chuẩn: HH:MM:SS AM (hay PM)90: void Time::PrintStandard() const91: {92: cout << ((Hour == 0 Hour == 12)? 12 : Hour % 12) << ":"93: << (Minute < 10? "0" : "") << Minute << ":"94: << (Second < 10? "0" : "") << Second95: << (Hour < 12? " AM" : " PM");96: }97:100: int main()101: {102: Time T;103:104: // Các lời gọi móc nối vào nhau 105: T.SetHour(18).SetMinute(30).SetSecond(22); 106: cout << "Military time: ";107: T.PrintMilitary();108: cout << endl << "Standard time: ";109: T.PrintStandard();110: cout << endl << endl << "New standard time: ";111: // Các lời gọi móc nối vào nhau112: T.SetTime(20, 20, 20).PrintStandard();113: cout << endl;114: return 0;115: } Các hàm thành viên SetTime(), SetHour(), SetMinute() và SetSecond() mỗi hàm đều trả về *this với kiểu trả về là Time &. Toán tử chấm liên kết từ trái sang phải, vì vậy biểu thức: T.SetHour(18).SetMinute(30).SetSecond(22); Đầu tiên gọi T.SetHour(18) thì trả về một tham chiếu tới đối tượng T là giá trị của lời gọi hàm này. Phần còn lại của biểu thức được hiểu như sau: T.SetMinute(30).SetSecond(22); T.SetMinute(30) gọi thực hiện và trả về tương đương của T. Phần còn của biểu thức là: T.SetSecond(22); Chúng ta chạy ví dụ 3.18, kết quả ở hình 3.19 4/8

Hình 3.19: Kết quả của ví dụ 3.18 CÁC ĐỐI TƯỢNG ĐƯỢC CẤP PHÁT ĐỘNG Các đối tượng có thể được cấp phát động giống như các dữ liệu khác bằng toán tử new và delete. Chẳng hạn: Time *TimePtr = new Time(1,20,26);.. delete TimePtr; CÁC THÀNH VIÊN TĨNH CỦA LỚP Bình thường, mỗi đối tượng của một lớp có bản sao chép của chính nó của tất cả các thành viên dữ liệu của lớp. Trong các trường hợp nhất định chỉ có duy nhất một bản chép thành viên dữ liệu đặc biệt cần phải dùng chung bởi tất cả các đối tượng của một lớp. Một thành viên dữ liệu tĩnh được sử dụng cho những điều đó và các lý do khác. Một thành viên dữ liệu tĩnh biểu diễn thông tin toàn lớp (class-wide). Khai báo một thành viên tĩnh bắt đầu với từ khóa static. Mặc dù các thành viên dữ liệu tĩnh có thể giống như các biến toàn cục, các thành viên dữ liệu tĩnh có phạm vi lớp. Các thành viên tĩnh có thể là public, private hoặc protected. Các thành viên dữ liệu tĩnh phải được khởi tạo một lần (và chỉ một lần) tại phạm vi file. Các thành viên lớp tĩnh public có thể được truy cập thông qua bất kỳ đối tượng nào của lớp đó, hoặc chúng có thể được truy cập thông qua tên lớp sử dụng toán tử định phạm vi. Các thành viên lớp tĩnh private và protected phải được truy cập thông qua các hàm thành viên public của lớp hoặc thông qua các friend của lớp. Các thành viên lớp tĩnh tồn tại ngay cả khi đối tượng của lớp đó không tồn tại. Để truy cập một thành viên lớp tĩnh public khi các đối tượng của lớp không tồn tại, đơn giản thêm vào đầu tên lớp và toán tử định phạm vi cho thành viên dữ liệu. Để truy cập một thành viên lớp tĩnh private hoặc protected khi các đối tượng của lớp không tồn tại, một hàm thành viên public phải được cung cấp và hàm phải được gọi bởi thêm vào đầu tên của nó với tên lớp và toán tử định phạm vi. 5/8

Ví dụ 3.19: Chương trình sau minh họa việc sử dụng thành viên dữ liệu tĩnh private và một hàm thành viên tĩnh public. CT3_19.CPP 1: #include <iostream.h>2: #include <string.h>3: #include <assert.h>4:5: class Employee6: {7: public:8: Employee(const char*, const char*); // Constructor9: ~Employee(); // Destructor10: char *GetFirstName() const; // Trả về first name11: char *GetLastName() const; // Trả về last name12: // Hàm thành viên tĩnh13: static int GetCount(); // Trả về số đối tượng khởi tạo14: private:15: char *FirstName;16: char *LastName;17: // static data member18: static int Count; // Số đối tượng khởi tạo19: };20:21: // Khởi tạo thành viên dữ liệu tĩnh22: int Employee::Count = 0;23:24: // Định nghĩa hàm thành viên tỉnh mà trả về số đối tượng khởi tạo25: int Employee::GetCount()26: {27: return Count;28: }29:30: // Constructor cấp phát động cho first name và last name31: Employee::Employee(const char *First, const char *Last)32: {33: FirstName = new char[ strlen(first) + 1 ];34: assert(firstname!= 0); // Bảo đảm vùng nhớ được cấp phát35: strcpy(firstname, First);36: LastName = new char[ strlen(last) + 1 ];37: assert(lastname!= 0); // Bảo đảm vùng nhớ được cấp phát38: strcpy(lastname, Last);39: ++Count; // Tăng số đối tượng lên 140: cout << "Employee constructor for " << FirstName41: << ' ' << LastName << " called." << endl;42: }43:44: // Destructor giải phóng vùng nhớ đã cấp phát45: Employee::~Employee()46: {47: cout << "~Employee() called for " << FirstName48: << ' ' << LastName << endl;49: delete FirstName;50: delete LastName;51: --Count; // Giảm số đối tượng xuống 152: }53:54: // Trả về first name55: char *Employee::GetFirstName() const56: {57: char *TempPtr = new char[strlen(firstname) + 1];58: assert(tempptr!= 0); // Bảo đảm vùng nhớ được cấp phát59: strcpy(tempptr, FirstName);60: return TempPtr;61: }62: 63: // Trả về last name64: char *Employee::GetLastName() const65: {66: char *TempPtr = new char[strlen(lastname) + 1];67: assert(tempptr!= 0); // Bảo đảm vùng nhớ được cấp phát68: strcpy(tempptr, LastName);69: return TempPtr;70: }71:72: int main()73: {74: cout << "Number of employees before instantiation is "75: << Employee::GetCount() << endl; // Sử dụng tên lớp76: Employee *E1Ptr = new Employee("Susan", "Baker");77: Employee *E2Ptr = new Employee("Robert", "Jones");78: cout << "Number of employees after instantiation is "79: << E1Ptr->GetCount() << endl;80: cout << endl << "Employee 1: "81: << E1Ptr->GetFirstName()82: << " " << E1Ptr- >GetLastName()83: << endl << "Employee 2: "84: << E2Ptr- >GetFirstName()85: << " " << E2Ptr->GetLastName() << endl << endl;86: delete E1Ptr;87: delete E2Ptr;88: cout << "Number of employees after deletion is "89: << Employee::GetCount() << endl;90: return 0;91: } 6/8

Thành viên dữ liệu Count được khởi tạo là zero ở phạm vi file với lệnh: int Employee::Count = 0; Thành viên dữ liệu Count duy trì số các đối tượng của lớp Employee đã được khởi tạo. Khi đối tượng của lớp Employee tồn tại, thành viên Count có thể được tham chiếu thông qua bất kỳ hàm thành viên nào của một đối tượng Employee trong ví dụ này, Count được tham chiếu bởi cả constructor lẫn destructor. Khi các đối tượng của lớp Employee không tồn tại, thành viên Count có thể vẫn được tham chiếu nhưng chỉ thông qua một lời gọi hàm thành viên tĩnh public GetCount() như sau: Employee::GetCount() Hàm GetCount() được sử dụng để xác định số các đối tượng của Employee khởi tạo hiện hành. Chú ý rằng khi không có các đối tượng trong chương trình, lời gọi hàm Employee::GetCount() được đưa ra. Tuy nhiên khi có các đối tượng khởi động hàm GetCount() có thể được gọi thông qua một trong các đối tượng như sau: E1Ptr->GetCount() Trong chương trình ở các dòng 34, 37, 58 và 67 sử dụng hàm assert() (định nghĩa trong assert.h). Hàm này kiểm tra giá trị của biểu thức. Nếu giá trị của biểu thức là 0 (false), hàm assert() in một thông báo lỗi và gọi hàm abort() (định nghĩa trong stdlib.h) để kết thúc chương trình thực thi. Nếu biểu thức có giá trị khác 0 (true) thì chương trình tiếp tục. Điều này rất có ích cho công cụ debug đối với việc kiểm tra nếu một biến có giá trị đúng. Chẳng hạn hàm ở dòng 34 hàm assert() kiểm tra con trỏ FirstName để xác định nếu nó không bằng 0 (null). Nếu điều kiện trong khẳng định (assertion) cho trước là đúng, chương trình tiếp tục mà không ngắt. Nếu điều kiện trong khẳng định cho trước là sai, một thông báo lỗi chứa số dòng, điều kiện được kiểm tra, và tên file trong đó sự khẳng định xuất hiện được in, và chương trình kết thúc. Khi đó lập trình viên có thể tập trung vào vùng này của đoạn mã để tìm lỗi. Các khẳng định không phải xóa từ chương trình khi debug xong. Khi các khẳng định không còn cần thiết cho mục đích debug trong một chương trình, dòng sau: #define NDEBUG được thêm vào ở đầu file chương trình. Điều này phát sinh tiền xử lý bỏ qua tất cả các khẳng định thay thế cho lập trình viên xóa mỗi khẳng định bằng tay. Chúng ta chạy ví dụ 3.19, kết quả ở hình 3.20 7/8

Hình 3.20: Kết quả của ví dụ 3.19 Một hàm thành viên có thể được khai báo là static nếu nó không truy cập đến các thành viên không tĩnh. Không giống như các thành viên không tĩnh, một hàm thành viên tĩnh không có con trỏ this bởi vì các thành viên dữ liệu tĩnh và các hàm thành viên tĩnh tồn tại độc lập với bất kỳ đối tượng nào của lớp. Chú ý: Hàm thành viên dữ liệu tĩnh không được là const. 8/8