Bất kỳ ngôn ngữ nào cung cấp tất cả các công cụ cần thiết để viết mã hướng đối tượng đều có thể được sử dụng để viết mã không hướng đối tượng Việc một ngôn ngữ nhất định có cung cấp các công cụ không hướng đối tượng hay không là không liên quan đến các cuộc thảo luận như thế này. Câu hỏi đơn giản là liệu ngôn ngữ đó có cung cấp tất cả các công cụ cần thiết để viết mã hướng đối tượng hay không Nếu lập luận tốt nhất mà bạn có thể đưa ra là C# không có đa kế thừa, thì điều đó không nói lên nhiều điều chống lại C#. Kế thừa nhiều (không giao diện) dường như không chỉ là một yêu cầu đối với mã hướng đối tượng, mà tôi muốn nói rằng đó là thứ không nên sử dụng trong mã hướng đối tượng tốt. Bạn có thể hoàn thành các mục tiêu cơ bản tương tự mà không cần sử dụng nó "Ưu tiên thành phần hơn thừa kế" Kế thừa cơ bản là một yêu cầu đối với thành phần, nhưng nó không nên là các cấu trúc cao hơn kế thừa phức tạp mà nên là những cấu trúc rất đơn giản, bằng phẳng, dễ hiểu Giả sử bạn muốn lắp ráp PC của riêng mình, bạn đến cửa hàng phần cứng và chọn bo mạch chủ, bộ xử lý, một số RAM, đĩa cứng, vỏ bọc, nguồn điện và lắp chúng lại với nhau. Bạn bật nguồn, và PC chạy. Bạn không cần lo lắng bo mạch chủ là bo mạch 4 lớp hay 6 lớp, ổ cứng có 4 hay 6 tấm; . Bạn chỉ cần đặt các thành phần phần cứng lại với nhau và mong muốn máy chạy. Tất nhiên, bạn phải đảm bảo rằng bạn có đúng giao diện, tôi. e. , bạn chọn đĩa cứng IDE thay vì đĩa cứng SCSI, nếu bo mạch chủ của bạn chỉ hỗ trợ IDE; . Tuy nhiên, không khó để thiết lập máy từ các thành phần phần cứng Tương tự, một chiếc ô tô được lắp ráp từ các bộ phận và linh kiện, chẳng hạn như khung gầm, cửa, động cơ, bánh xe, phanh và hộp số. Các thành phần có thể tái sử dụng, e. g. , một bánh xe có thể sử dụng cho nhiều xe ô tô (cùng thông số kỹ thuật) Phần cứng, chẳng hạn như máy tính và ô tô, được lắp ráp từ các bộ phận, là các bộ phận có thể tái sử dụng Làm thế nào về phần mềm? . Không giống như phần cứng, rất khó để "lắp ráp" một ứng dụng từ các thành phần phần mềm. Kể từ khi máy tính ra đời cách đây 60 năm, chúng tôi đã viết hàng tấn chương trình. Tuy nhiên, đối với mỗi ứng dụng mới, chúng tôi phải phát minh lại các bánh xe và viết chương trình từ đầu Tại sao lại phát minh ra các bánh xe? Ngôn ngữ hướng thủ tục truyền thốngChúng ta có thể làm điều này bằng ngôn ngữ lập trình hướng thủ tục truyền thống như C, Fortran, Cobol hoặc Pascal không? Các ngôn ngữ định hướng thủ tục truyền thống (chẳng hạn như C và Pascal) có một số nhược điểm đáng chú ý trong việc tạo các thành phần phần mềm có thể tái sử dụng
Tóm lại, các ngôn ngữ thủ tục truyền thống tách cấu trúc dữ liệu và thuật toán của các thực thể phần mềm Vào đầu những năm 1970, Bộ Quốc phòng Hoa Kỳ (DoD) đã ủy quyền cho một lực lượng đặc nhiệm điều tra lý do tại sao ngân sách CNTT của họ luôn nằm ngoài tầm kiểm soát; . Những phát hiện là
Lực lượng đặc nhiệm được đề xuất để làm cho phần mềm hoạt động giống như ĐỐI TƯỢNG phần cứng. Sau đó, DoD thay thế hơn 450 ngôn ngữ máy tính, sau đó được sử dụng để xây dựng các hệ thống DoD, bằng một ngôn ngữ hướng đối tượng có tên là Ada Ngôn ngữ lập trình hướng đối tượngCác ngôn ngữ lập trình hướng đối tượng (OOP) được thiết kế để khắc phục những vấn đề này
Ví dụ: giả sử bạn muốn viết một trò chơi bóng đá trên máy tính (mà tôi coi là một ứng dụng phức tạp). Khá khó để mô hình hóa trò chơi bằng các ngôn ngữ hướng thủ tục. Nhưng sử dụng các ngôn ngữ OOP, bạn có thể dễ dàng mô hình hóa chương trình theo những “vật thật” xuất hiện trong các trận bóng
Quan trọng nhất, một số lớp này (chẳng hạn như Circle(double r = 1.0, string c = "red") { radius = r; color = c; }0 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }1) có thể được sử dụng lại trong một ứng dụng khác, chẳng hạn như. g. , trò chơi bóng rổ trên máy tính, ít hoặc không sửa đổi Lợi ích của OOPCác ngôn ngữ hướng thủ tục tập trung vào các thủ tục, với chức năng là đơn vị cơ bản. Trước tiên, bạn cần tìm ra tất cả các chức năng và sau đó nghĩ về cách biểu diễn dữ liệu Các ngôn ngữ hướng đối tượng tập trung vào các thành phần mà người dùng cảm nhận được, với các đối tượng là đơn vị cơ bản. Bạn tìm ra tất cả các đối tượng bằng cách đặt tất cả dữ liệu và hoạt động mô tả tương tác của người dùng với dữ liệu Công nghệ hướng đối tượng có nhiều lợi ích
Khái niệm cơ bản về OOPCác lớp và trường hợpLớp. Một lớp là một định nghĩa của các đối tượng cùng loại. Nói cách khác, một lớp là một bản thiết kế, khuôn mẫu hoặc nguyên mẫu xác định và mô tả các thuộc tính tĩnh và hành vi động chung cho tất cả các đối tượng cùng loại Ví dụ. Một thể hiện là một hiện thực của một mục cụ thể của một lớp. Nói cách khác, một thể hiện là sự khởi tạo của một lớp. Tất cả các thể hiện của một lớp đều có các thuộc tính giống nhau, như được mô tả trong định nghĩa lớp. Ví dụ: bạn có thể định nghĩa một lớp có tên là " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }2" và tạo ba thể hiện của lớp " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }2" cho "_______04", " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }5" và " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }6" Thuật ngữ "đối tượng" thường dùng để chỉ ví dụ. Nhưng nó thường được sử dụng khá lỏng lẻo, có thể đề cập đến một lớp hoặc một thể hiện Một Lớp là Hộp 3 Ngăn đóng gói Dữ liệu và Chức năngCó thể hình dung một lớp học như một chiếc hộp ba ngăn, như hình minh họa
Nói cách khác, một lớp đóng gói các thuộc tính tĩnh (dữ liệu) và các hành vi động (các thao tác hoạt động trên dữ liệu) trong một hộp. thành viên lớp. Các thành viên dữ liệu và các hàm thành viên được gọi chung là các thành viên lớp Hình dưới đây cho thấy một vài ví dụ về các lớp Hình dưới đây cho thấy hai trường hợp của lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }2, được xác định là " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }8" và " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }9" Sơ đồ sơ đồ lớp và ngôn ngữ mô hình hóa thống nhất (UML). Các sơ đồ lớp trên được vẽ theo các ký hiệu UML. Một lớp được biểu diễn dưới dạng hộp 3 ngăn, lần lượt chứa tên, dữ liệu thành viên (biến) và hàm thành viên. tên lớp được in đậm và tập trung. Một thể hiện (đối tượng) cũng được biểu diễn dưới dạng hộp 3 ngăn, với tên thể hiện là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 và được gạch dưới Bản tóm tắt ngắn gọn
Định nghĩa lớpTrong C++, chúng ta sử dụng từ khóa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }01 để định nghĩa một lớp. Có hai phần trong khai báo lớp. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03, sẽ giải thích sau. Ví dụ như, Quy ước đặt tên lớp. Một tên lớp sẽ là một danh từ hoặc một cụm danh từ được tạo thành từ nhiều từ. Tất cả các từ sẽ được viết hoa đầu tiên (trường hợp lạc đà). Sử dụng một danh từ số ít cho tên lớp. Chọn một tên lớp có ý nghĩa và tự mô tả. Ví dụ: ________ 104, ________ 105, _____ 106, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07 và ________ 108 Tạo thể hiện của một lớpĐể tạo một thể hiện của một lớp, bạn phải
Ví dụ, giả sử rằng chúng ta có một lớp tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, chúng ta có thể tạo các thể hiện của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 như sau Ngoài ra, bạn có thể gọi hàm tạo một cách rõ ràng bằng cú pháp sau chấm (. ) Nhà điều hànhĐể tham chiếu một thành viên của một đối tượng (thành viên dữ liệu hoặc hàm thành viên), bạn phải
Ví dụ, giả sử rằng chúng ta có một lớp tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, với hai thành viên dữ liệu ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15) và hai hàm ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17). Chúng tôi đã tạo ba phiên bản của lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, cụ thể là, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }19, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }01. Để gọi hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17, trước tiên bạn phải xác định đối tượng quan tâm, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 nói, sau đó sử dụng toán tử dấu chấm, ở dạng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }04, để gọi hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17 của đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 Ví dụ, Gọi Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17 mà không xác định thực thể là vô nghĩa, vì bán kính không xác định (có thể có nhiều thực thể của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 - mỗi thực thể duy trì bán kính riêng của nó) Nói chung, giả sử có một lớp tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 với một thành viên dữ liệu tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 và một hàm thành viên tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }01. Một thể hiện có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 được xây dựng cho Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09. Bạn sử dụng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }04 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }05 Thành viên dữ liệu (Biến)Thành viên dữ liệu (biến) có tên (hoặc mã định danh) và loại; . Một thành viên dữ liệu cũng có thể là một thể hiện của một lớp nào đó (sẽ được thảo luận sau) Quy ước đặt tên thành viên dữ liệu. Tên thành viên dữ liệu sẽ là một danh từ hoặc một cụm danh từ được tạo thành từ nhiều từ. Từ đầu tiên được viết thường và các từ còn lại được viết hoa chữ cái đầu (camel-case), e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }06, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }08, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00. Hãy lưu ý rằng tên biến bắt đầu bằng chữ thường, trong khi tên lớp bắt đầu bằng chữ hoa Chức năng thành viênMột chức năng thành viên (như được mô tả trong chương trước)
Quy ước đặt tên hàm thành viên. Tên hàm phải là một động từ hoặc một cụm động từ được tạo thành từ nhiều từ. Từ đầu tiên viết thường và các từ còn lại viết hoa chữ cái đầu (camel-case). Ví dụ: Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 Lưu ý rằng tên thành viên dữ liệu là một danh từ (biểu thị một thuộc tính tĩnh), trong khi tên hàm là một động từ (biểu thị một hành động). Họ có cùng một quy ước đặt tên. Tuy nhiên, bạn có thể dễ dàng phân biệt chúng từ ngữ cảnh. Các hàm nhận đối số trong dấu ngoặc đơn (có thể là đối số không với dấu ngoặc đơn trống), nhưng biến thì không. Trong văn bản này, các chức năng được biểu thị bằng một cặp dấu ngoặc đơn, e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17 cho rõ ràng Đặt chúng lại với nhau. Một ví dụ OOPMột lớp có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 sẽ được định nghĩa như minh họa trong sơ đồ lớp. Nó chứa hai thành viên dữ liệu. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 (loại Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07) và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 (loại Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09); . Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }101 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }17 Sau đó, ba phiên bản của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 được gọi là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }19, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }00 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }01 sẽ được xây dựng với các thành viên dữ liệu tương ứng của chúng, như thể hiện trong sơ đồ phiên bản Trong ví dụ này, chúng tôi sẽ giữ tất cả các mã trong một tệp nguồn duy nhất có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }107 CircleAIO. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }8 Để biên dịch và chạy chương trình (với GNU GCC trong Windows) Circle(double r = 1.0, string c = "red") { radius = r; color = c; }1 nhà xây dựngHàm tạo là một hàm đặc biệt có tên hàm trùng với tên lớp. Trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 ở trên, chúng tôi định nghĩa một hàm tạo như sau Một hàm tạo được sử dụng để xây dựng và khởi tạo tất cả các thành viên dữ liệu. Để tạo một thể hiện mới của một lớp, bạn cần khai báo tên của thể hiện và gọi hàm tạo. Ví dụ, Hàm tạo khác với hàm thông thường ở các khía cạnh sau
Đối số mặc định cho hàmTrong C++, bạn có thể chỉ định giá trị mặc định cho các đối số theo sau của hàm (bao gồm hàm tạo) trong tiêu đề hàm. Ví dụ, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }3 "công khai" vs. Công cụ sửa đổi kiểm soát truy cập "riêng tư"Công cụ sửa đổi kiểm soát truy cập có thể được sử dụng để kiểm soát khả năng hiển thị của thành viên dữ liệu hoặc chức năng thành viên trong một lớp. Chúng tôi bắt đầu với hai công cụ sửa đổi kiểm soát truy cập sau đây
Ví dụ: trong định nghĩa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 ở trên, thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 được khai báo là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02. Kết quả là, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 có thể truy cập bên trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, nhưng KHÔNG thể truy cập bên ngoài lớp. Nói cách khác, bạn không thể sử dụng " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }118" để chỉ Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }19 trong Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121. Hãy thử chèn câu lệnh "______6122" vào Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 và quan sát thông báo lỗi Circle(double r = 1.0, string c = "red") { radius = r; color = c; }7 Hãy thử di chuyển Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 đến phần Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03 và chạy lại câu lệnh Mặt khác, hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16 được khai báo Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03 trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09. Do đó, nó có thể được gọi trong Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 Ký hiệu UML. Trong ký hiệu UML, các thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03 được biểu thị bằng " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }131", trong khi các thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 có " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }133" trong sơ đồ lớp Ẩn thông tin và đóng góiMột lớp đóng gói các thuộc tính tĩnh và các hành vi động vào một "chiếc hộp 3 ngăn". Khi một lớp được xác định, bạn có thể niêm phong "hộp" và đặt "hộp" lên giá để người khác sử dụng và tái sử dụng. Bất cứ ai cũng có thể nhặt "hộp" và sử dụng nó trong ứng dụng của họ. Điều này không thể thực hiện được trong ngôn ngữ định hướng thủ tục truyền thống như C, vì các thuộc tính tĩnh (hoặc biến) nằm rải rác trên toàn bộ chương trình và tệp tiêu đề. Bạn không thể "cắt" một phần của chương trình C, cắm vào một chương trình khác và mong chương trình chạy mà không có nhiều thay đổi Thành viên dữ liệu của một lớp thường được ẩn từ bên ngoài, với công cụ sửa đổi kiểm soát truy cập Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02. Quyền truy cập vào các thành viên dữ liệu riêng tư được cung cấp thông qua các chức năng của người đánh giá Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03, e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }101 Điều này tuân theo nguyên tắc che giấu thông tin. Nghĩa là, các đối tượng giao tiếp với nhau bằng các giao diện được xác định rõ (các hàm công khai). Các đối tượng không được phép biết chi tiết thực hiện của người khác. Các chi tiết triển khai được ẩn hoặc gói gọn trong lớp. Ẩn thông tin tạo điều kiện sử dụng lại lớp quy tắc ngón tay cái. Không tạo bất kỳ thành viên dữ liệu nào Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03, trừ khi bạn có lý do chính đáng Getters và SettersĐể cho phép người khác đọc giá trị của thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }140, bạn sẽ cung cấp hàm get (hoặc hàm getter hoặc hàm truy cập) có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }141. Một getter không cần hiển thị dữ liệu ở định dạng thô. Nó có thể xử lý dữ liệu và giới hạn chế độ xem dữ liệu mà những người khác sẽ thấy. Getters sẽ không sửa đổi thành viên dữ liệu Để cho phép các lớp khác sửa đổi giá trị của thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }140, bạn sẽ cung cấp một hàm set (hoặc hàm setter hoặc mutator) có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }144. Một trình thiết lập có thể cung cấp xác thực dữ liệu (chẳng hạn như kiểm tra phạm vi) và chuyển đổi dữ liệu thô thành biểu diễn bên trong Ví dụ, trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 của chúng ta, các thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 được khai báo là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02. Điều đó có nghĩa là, chúng chỉ khả dụng trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 và không hiển thị bên ngoài lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 - bao gồm cả Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121. Bạn không thể truy cập trực tiếp các thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 từ Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 - thông qua nói Circle(double r = 1.0, string c = "red") { radius = r; color = c; }118 hoặc Circle(double r = 1.0, string c = "red") { radius = r; color = c; }157. Lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 cung cấp hai hàm truy cập công khai, cụ thể là, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }16 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }101. Các hàm này được khai báo Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 có thể gọi các hàm truy cập công khai này để truy xuất Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 của một đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, thông qua nói Circle(double r = 1.0, string c = "red") { radius = r; color = c; }166 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }167 Không có cách nào bạn có thể thay đổi Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 hoặc Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 của một đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, sau khi nó được xây dựng trong Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121. Bạn không thể đưa ra các câu lệnh như Circle(double r = 1.0, string c = "red") { radius = r; color = c; }172 để thay đổi Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 của thể hiện Circle(double r = 1.0, string c = "red") { radius = r; color = c; }19, vì Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 được khai báo là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 và không hiển thị đối với người khác bao gồm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 Nếu người thiết kế của lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 cho phép thay đổi Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }15 sau khi đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 được xây dựng, anh ta phải cung cấp trình thiết lập thích hợp, e. g. , Với việc triển khai ẩn thông tin đúng cách, người thiết kế lớp có toàn quyền kiểm soát những gì người dùng của lớp có thể và không thể làm Từ khóa "cái này"Bạn có thể sử dụng từ khóa " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183" để chỉ trường hợp này bên trong một định nghĩa lớp Một trong những cách sử dụng chính của từ khóa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183 là giải quyết sự mơ hồ giữa tên của thành viên dữ liệu và tham số chức năng. Ví dụ, Trong các mã trên, có hai định danh được gọi là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 - một thành viên dữ liệu và tham số chức năng. Điều này gây ra xung đột đặt tên. Để giải quyết xung đột đặt tên, bạn có thể đặt tên cho tham số chức năng là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }186 thay vì Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14. Tuy nhiên, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 gần đúng và có ý nghĩa hơn trong ngữ cảnh này. Bạn có thể sử dụng từ khóa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183 để giải quyết xung đột đặt tên này. "______6190" đề cập đến thành viên dữ liệu; " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183" thực sự là một con trỏ tới đối tượng này. Tôi sẽ giải thích về con trỏ và ý nghĩa của toán tử " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }193" sau Ngoài ra, bạn có thể sử dụng tiền tố (chẳng hạn như Circle(double r = 1.0, string c = "red") { radius = r; color = c; }194) hoặc hậu tố (chẳng hạn như Circle(double r = 1.0, string c = "red") { radius = r; color = c; }195) để đặt tên cho các thành viên dữ liệu nhằm tránh sự cố về tên. Ví dụ, Trình biên dịch C++ đặt tên nội bộ cho các thành viên dữ liệu của chúng bắt đầu bằng dấu gạch dưới ở đầu ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }196) và các biến cục bộ có 2 dấu gạch dưới ở đầu (e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }197). Do đó, tránh đặt tên bắt đầu bằng dấu gạch dưới trong chương trình của bạn Hàm thành viên "const"Hàm thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198, được xác định bởi từ khóa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198 ở cuối tiêu đề của hàm thành viên, không thể sửa đổi bất kỳ thành viên dữ liệu nào của đối tượng này. Ví dụ, Quy ước cho Getters/Setters và ConstructorCác hàm tạo, getter và setter cho thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }140 thuộc loại Circle(double r = 1.0, string c = "red") { radius = r; color = c; }302 trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }303 có các quy ước sau Đối với một biến Circle(double r = 1.0, string c = "red") { radius = r; color = c; }304 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }140, getter sẽ được đặt tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }306, thay vì Circle(double r = 1.0, string c = "red") { radius = r; color = c; }141, như sau Nhà xây dựng mặc địnhHàm tạo mặc định là hàm tạo không có tham số hoặc có giá trị mặc định cho tất cả các tham số. Ví dụ: hàm tạo của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 ở trên có thể được dùng làm hàm tạo mặc định với tất cả các tham số mặc định Nếu C++, nếu bạn không cung cấp BẤT KỲ hàm tạo nào, trình biên dịch sẽ tự động cung cấp một hàm tạo mặc định mà không làm gì cả. Đó là, Trình biên dịch sẽ không cung cấp hàm tạo mặc định nếu bạn xác định (các) hàm tạo bất kỳ. Nếu tất cả các hàm tạo mà bạn đã xác định đều yêu cầu đối số, thì việc gọi hàm tạo mặc định không có đối số sẽ dẫn đến lỗi. Điều này là để cho phép người thiết kế lớp không thể tạo một thể hiện chưa được khởi tạo, bằng cách KHÔNG cung cấp một hàm tạo mặc định rõ ràng Danh sách khởi tạo thành viên của nhà xây dựngThay vì khởi tạo các thành viên dữ liệu riêng tư bên trong phần thân của hàm tạo, như sau Circle(double r = 1.0, string c = "red") { radius = r; color = c; } Chúng ta có thể sử dụng một cú pháp thay thế được gọi là danh sách khởi tạo thành viên như sau Circle(double r = 1.0, string c = "red") { radius = r; color = c; }0 Danh sách khởi tạo thành viên được đặt sau tiêu đề của hàm tạo, được phân tách bằng dấu hai chấm ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }309). Mỗi bộ khởi tạo có dạng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }310. Đối với loại cơ bản, nó tương đương với Circle(double r = 1.0, string c = "red") { radius = r; color = c; }311. Đối với đối tượng, hàm tạo sẽ được gọi để xây dựng đối tượng. Phần thân của hàm tạo (trống trong trường hợp này) sẽ được chạy sau khi hoàn thành danh sách bộ khởi tạo thành viên Nên sử dụng danh sách trình khởi tạo thành viên để khởi tạo tất cả các thành viên dữ liệu, vì nó thường hiệu quả hơn so với thực hiện phép gán bên trong phần thân của hàm tạo * Kẻ hủy diệtHàm hủy, tương tự như hàm tạo, là một hàm đặc biệt có cùng tên với tên lớp, với tiền tố Circle(double r = 1.0, string c = "red") { radius = r; color = c; }312, e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }313. Hàm hủy được gọi ngầm khi một đối tượng bị hủy Nếu bạn không xác định hàm hủy, trình biên dịch sẽ cung cấp một giá trị mặc định, không có tác dụng gì Ghi chú nâng cao
* Sao chép Trình xây dựngTrình xây dựng bản sao xây dựng một đối tượng mới bằng cách sao chép một đối tượng hiện có cùng loại. Nói cách khác, một hàm tạo bản sao nhận một đối số, là một đối tượng của cùng một lớp Nếu bạn không định nghĩa một hàm tạo sao chép, trình biên dịch sẽ cung cấp một mặc định để sao chép tất cả các thành viên dữ liệu của đối tượng đã cho. Ví dụ, Trình tạo bản sao đặc biệt quan trọng. Khi một đối tượng được truyền vào một hàm theo giá trị, hàm tạo sao chép sẽ được sử dụng để tạo một bản sao của đối số Ghi chú nâng cao
* Sao chép toán tử gán (=)Trình biên dịch cũng cung cấp một toán tử gán mặc định ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }321), có thể được sử dụng để gán một đối tượng cho một đối tượng khác của cùng một lớp thông qua bản sao thành viên. Ví dụ, sử dụng lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 được định nghĩa trước đó, Ghi chú nâng cao
Separating Header and ImplementationFor better software engineering, it is recommended that the class declaration and implementation be kept in 2 separate files. declaration is a header file " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }326"; while implementation in a " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }327". This is known as separating the public interface (header declaration) and the implementation. Interface is defined by the designer, implementation can be supplied by others. While the interface is fixed, different vendors can provide different implementations. Furthermore, only the header files are exposed to the users, the implementation can be provided in an object file " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }328" (or in a library). The source code needs not given to the users I shall illustrate with the following examples Example. The Circle ClassInstead of putting all the codes in a single file. We shall "separate the interface and implementation" by placing the codes in 3 files
Circle. h - HeaderCircle(double r = 1.0, string c = "red") { radius = r; color = c; }1 Program Notes
Các tệp tiêu đề sẽ chứa các hằng số, nguyên mẫu hàm, khai báo lớp/cấu trúc Vòng tròn. cpp - Thực hiệnCircle(double r = 1.0, string c = "red") { radius = r; color = c; }0 Program Notes
Biên soạn lớp CircleBạn có thể biên dịch Circle(double r = 1.0, string c = "red") { radius = r; color = c; }331 thành một tệp đối tượng có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }342, thông qua tùy chọn Circle(double r = 1.0, string c = "red") { radius = r; color = c; }343 (chỉ biên dịch) trong GNU GCC Circle(double r = 1.0, string c = "red") { radius = r; color = c; }11 Để sử dụng lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, người dùng cần có Circle(double r = 1.0, string c = "red") { radius = r; color = c; }329 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }342. Anh ấy không cần Circle(double r = 1.0, string c = "red") { radius = r; color = c; }331. Nói cách khác, bạn không cần cung cấp mã nguồn của mình mà chỉ cung cấp các khai báo công khai và mã đối tượng. TestCircle. cpp - Trình điều khiển thử nghiệmHãy viết chương trình thử nghiệm sử dụng lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09 đã tạo Circle(double r = 1.0, string c = "red") { radius = r; color = c; }12 Biên dịch chương trình thử nghiệmĐể biên dịch Circle(double r = 1.0, string c = "red") { radius = r; color = c; }333 với mã đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }342 (và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }329) Circle(double r = 1.0, string c = "red") { radius = r; color = c; }13 Bạn cũng có thể biên dịch Circle(double r = 1.0, string c = "red") { radius = r; color = c; }333 với mã nguồn Circle(double r = 1.0, string c = "red") { radius = r; color = c; }331 (và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }329) Circle(double r = 1.0, string c = "red") { radius = r; color = c; }14 Hãy viết một lớp có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355, lớp này mô hình hóa một thể hiện thời gian cụ thể với các giá trị giờ, phút và giây, như thể hiện trong sơ đồ lớp. Lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355 chứa các thành viên sau
Hãy viết mã cho lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355, với tiêu đề và phần triển khai được tách thành hai tệp. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }388 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }389 Tiêu đề - Thời gian. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }15 Thời gian mổ xẻ. h#ifndef TIME_H Circle(double r = 1.0, string c = "red") { radius = r; color = c; }390), chúng tôi gói mã tiêu đề trong một cặp chỉ thị tiền xử lý Circle(double r = 1.0, string c = "red") { radius = r; color = c; }391 (nếu không xác định) và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }392. Các mã trong khối if sẽ chỉ được đưa vào nếu mã định danh Circle(double r = 1.0, string c = "red") { radius = r; color = c; }393 chưa được xác định. Điều này đúng với lần đưa vào đầu tiên, cũng xác định mã định danh Circle(double r = 1.0, string c = "red") { radius = r; color = c; }393 (chỉ thị đầu tiên trong phần thân của khối if). Không thể đưa vào tiếp theo, vì Circle(double r = 1.0, string c = "red") { radius = r; color = c; }393 đã được xác định trong lần đưa vào đầu tiên. Theo quy ước, sử dụng mã định danh Circle(double r = 1.0, string c = "red") { radius = r; color = c; }396 (hoặc Circle(double r = 1.0, string c = "red") { radius = r; color = c; }397) cho tiêu đề Circle(double r = 1.0, string c = "red") { radius = r; color = c; }398. Giờ học { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }388 chứa khai báo lớp cho lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355. Nó được chia thành hai phần. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03. Các thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 (dữ liệu hoặc hàm) chỉ có thể được truy cập bởi các thành viên của lớp này, trong khi tất cả các thành viên của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03 đều có thể nhìn thấy (chẳng hạn như hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }121 nằm ngoài lớp). Khai báo lớp phải được kết thúc bằng dấu chấm phẩy. riêng tư. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360. Trong C++98/C++03, bạn KHÔNG được phép khởi tạo thành viên dữ liệu trong khai báo lớp (ngoại trừ thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }336 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }711). Ví dụ: cài đặt Circle(double r = 1.0, string c = "red") { radius = r; color = c; }712 gây ra lỗi biên dịch. Thay vào đó, các thành viên dữ liệu sẽ được khởi tạo trong hàm tạo (sẽ được hiển thị sau). C++ 11 mới hơn cho phép khởi tạo các thành viên dữ liệu. Chỉ các nguyên mẫu hàm thành viên được liệt kê trong khai báo lớp. Nguyên mẫu hàm bao gồm kiểu trả về, tên hàm và kiểu tham số Time(int h = 0, int m = 0, int s = 0); Circle(double r = 1.0, string c = "red") { radius = r; color = c; }109. Không có câu lệnh Circle(double r = 1.0, string c = "red") { radius = r; color = c; }110 nào được phép bên trong phần thân của hàm tạo. Một hàm tạo chỉ có thể được sử dụng trong quá trình khai báo cá thể để khởi tạo các thành viên dữ liệu của cá thể. Nó không thể được gọi sau đó. Trong các nguyên mẫu hàm của tiêu đề, chúng ta có thể đặt giá trị mặc định của các tham số của hàm cho bất kỳ thành viên hàm nào bằng cách sử dụng " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }715". Trong trường hợp này, hàm tạo này có thể được gọi với 0 đến 3 đối số, các đối số theo sau bị bỏ qua sẽ được đặt thành giá trị mặc định của chúng, e. g. , Các mã định danh Circle(double r = 1.0, string c = "red") { radius = r; color = c; }716, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }717 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }718 không cần thiết trong nguyên mẫu hàm - bạn chỉ cần chỉ định loại tham số. Nhưng chúng đóng vai trò là tài liệu phù hợp và được khuyến nghị mạnh mẽ int getHour() const; Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360. Since the data members are Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 and are not accessible outside the class, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }03 getters and setters are often provided to read and modify the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 data members. By convention, a getter receives nothing ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }109) from the caller and returns a value of the type of the data member; a setter receives a value of the type of the data member and returns Circle(double r = 1.0, string c = "red") { radius = r; color = c; }109. Setters may validate the input before setting the value of the data member. Chúng ta khai báo hằng hàm getter bằng cách đặt từ khóa Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198 sau danh sách tham số của hàm. Hàm thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198 không thể sửa đổi bất kỳ thành viên dữ liệu nào của đối tượng này. Getter không cần sửa đổi bất kỳ thành viên dữ liệu nào. void setTime(int h, int m, int s); Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360 của phiên bản này trong một lần gọi. void print() const; Circle(double r = 1.0, string c = "red") { radius = r; color = c; }732, không điền, e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }733. Hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }378 trả về Circle(double r = 1.0, string c = "red") { radius = r; color = c; }109. void nextSecond(); Circle(double r = 1.0, string c = "red") { radius = r; color = c; }385 trở thành Circle(double r = 1.0, string c = "red") { radius = r; color = c; }386. Hàm Circle(double r = 1.0, string c = "red") { radius = r; color = c; }383 trả về Circle(double r = 1.0, string c = "red") { radius = r; color = c; }109. Thời gian thực hiện. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }16 Thời gian mổ xẻ. cppTệp triển khai Circle(double r = 1.0, string c = "red") { radius = r; color = c; }389 chứa các định nghĩa của thành viên (trong khi tệp tiêu đề chứa các khai báo), cụ thể là các hàm thành viên Tất cả các định danh của thành viên trong quá trình triển khai được đặt trước tên lớp và toán tử phân giải phạm vi ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }741), e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }742 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }743, để trình biên dịch có thể biết rằng các mã định danh này thuộc về một lớp cụ thể, trong trường hợp này là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355 Thời gian. Thời gian(int h, int m, int s) { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }711, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07) thành viên dữ liệu. Nó cũng KHÔNG đưa ra thông báo lỗi nếu bạn sử dụng thành viên dữ liệu trước khi nó được khởi tạo. Do đó, chúng tôi khuyên bạn nên khởi tạo tất cả các thành viên dữ liệu trong hàm tạo để phiên bản được xây dựng hoàn tất, thay vì dựa vào người dùng để đặt giá trị của các thành viên dữ liệu sau khi xây dựng. } In the constructor, we initialize the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 data members Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360 based on the inputs provided by the caller. C++ does NOT initialize fundamental-type (e.g., Circle(double r = 1.0, string c = "red") { radius = r; color = c; }711, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07) data members. It also does NOT issue an error message if you use an data member before it is initialized. Hence, It is strongly recommended to initialize all the data members in the constructor, so that the constructed instance is complete, instead of relying on the user to set the values of the data members after construction. Các giá trị mặc định của các tham số được chỉ định trong khai báo lớp (trong tiêu đề), KHÔNG phải trong định nghĩa hàm. Đặt một giá trị mặc định trong định nghĩa hàm (e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }751) gây ra lỗi biên dịch Hãy lưu ý rằng chúng tôi chưa bao gồm xác thực đầu vào (e. g. , giờ sẽ nằm trong khoảng từ 0 đến 23) trong hàm tạo (và bộ cài đặt). Chúng ta sẽ làm điều đó trong ví dụ sau int Thời gian. getHour() const { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358 chỉ cần trả về giá trị của . Thời gian vô hiệu. setHour(int h) { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358 đặt thành viên dữ liệu . Một lần nữa, không có xác thực đầu vào cho h (phải nằm trong khoảng từ 0 đến 23). The rest of the function definitions are self-explanatory "this" PointerInstead of naming the function parameters Circle(double r = 1.0, string c = "red") { radius = r; color = c; }716, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }717 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }718, we would like to name the parameters Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360, which are semantically more meaningful. However, these names crashes with the names of private data members. C++ provides a keyword Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183 (which is a pointer to this instance - to be discussed later) to differentiate between the data members and function parameters. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }764, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }765 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }766 refer to the data members; while Circle(double r = 1.0, string c = "red") { radius = r; color = c; }358, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }359, and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }360 refer to the function parameters. We can rewrite the constructor and setter as follows Member Initializer ListC++ provide an alternative syntax to initialize data members in the constructor called member initializer list. For example, The member initializer list is placed after the function parameter list, separated by a colon, in the form of Circle(double r = 1.0, string c = "red") { radius = r; color = c; }770. For fundamental-type data members (e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }711, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }07), Circle(double r = 1.0, string c = "red") { radius = r; color = c; }773 is the same as Circle(double r = 1.0, string c = "red") { radius = r; color = c; }774. For object data members (to be discussed later), the copy constructor will be invoked. The function body will be executed after the member initializer list, which is empty in this case The data members in the initializer list are initialized in the order of their declarations in the class declaration, not the order in the initializer list Test Driver - TestTime. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }17 Thời gian kiểm tra mổ xẻ. cppTrình điều khiển thử nghiệm kiểm tra hàm tạo (có và không có giá trị mặc định) và tất cả các chức năng thành viên chung. Rõ ràng, không có xác thực đầu vào nào được thực hiện, như được phản ánh trong ví dụ Circle(double r = 1.0, string c = "red") { radius = r; color = c; }775 Tập thể dụcThêm các hàm thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }776, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }777, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }778, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }779, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }780 vào lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }355 Biên dịch chương trìnhBạn có thể compile tất cả các file nguồn lại với nhau để được file thực thi như sau Circle(double r = 1.0, string c = "red") { radius = r; color = c; }18 Ngoài ra, bạn có thể biên dịch Circle(double r = 1.0, string c = "red") { radius = r; color = c; }389 thành tệp đối tượng Circle(double r = 1.0, string c = "red") { radius = r; color = c; }783, sau đó trình điều khiển thử nghiệm với tệp đối tượng. Bằng cách này, bạn chỉ phân phối tệp đối tượng và tệp tiêu đề chứ không phải tệp nguồn Circle(double r = 1.0, string c = "red") { radius = r; color = c; }19 Thí dụ. lớp điểmLớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }784, như thể hiện trong sơ đồ lớp, mô hình các điểm 2D với tọa độ x và y Trong sơ đồ lớp, " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }133" biểu thị thành viên Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02; . "______8789" chỉ định giá trị mặc định của thành viên dữ liệu Lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }784 chứa các nội dung sau
Điểm. h - Tiêu đềCircle(double r = 1.0, string c = "red") { radius = r; color = c; }1 Điểm. cpp - Thực hiệnCircle(double r = 1.0, string c = "red") { radius = r; color = c; }31 Điểm kiểm tra. cpp - Trình điều khiển thử nghiệmCircle(double r = 1.0, string c = "red") { radius = r; color = c; }1 Thí dụ. Lớp tài khoảnMột lớp có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }09, mô hình hóa một tài khoản ngân hàng, được thiết kế như trong sơ đồ lớp. Nó chứa
Tệp tiêu đề - Tài khoản. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }33 Hồ sơ thực hiện - Tài khoản. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }34 Trình điều khiển thử nghiệm - TestAccount. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }3 Thí dụ. Lớp bóngMột lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }0 mô hình một quả bóng đang chuyển động, được thiết kế như trong sơ đồ lớp, bao gồm các thành viên sau
Tệp Tiêu đề - Bóng. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }36 File Thực Hiện - Bóng. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }37 Lái thử - TestBall. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }38 Hãy bắt đầu với lớp Tác giảHãy bắt đầu với một lớp có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36, được thiết kế như trong sơ đồ lớp. Nó chứa
Tệp tiêu đề - Tác giả. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }39 Hồ sơ thực hiện - Tác giả. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }70 Mổ xẻ tác giả. cppTác giả. Tác giả(tên chuỗi, chuỗi email, giới tính ký tự) { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }38 in the function's parameter, which crashes with the data member's identifier Circle(double r = 1.0, string c = "red") { radius = r; color = c; }38. To differentiate between the two identifiers, we use the keyword Circle(double r = 1.0, string c = "red") { radius = r; color = c; }183, which is a pointer to this instance. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }60 refers to the data member; while Circle(double r = 1.0, string c = "red") { radius = r; color = c; }38 refers to the function's parameter. Không có xác thực đầu vào nào được thực hiện trên tham số Circle(double r = 1.0, string c = "red") { radius = r; color = c; }38. Mặt khác, đối với Circle(double r = 1.0, string c = "red") { radius = r; color = c; }40, chúng tôi gọi setter Circle(double r = 1.0, string c = "red") { radius = r; color = c; }64 thực hiện xác thực đầu vào. if (giới tính == 'm'. giới tính == 'f') { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }42 ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }44, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }45, or Circle(double r = 1.0, string c = "red") { radius = r; color = c; }46 for unknown). We assign Circle(double r = 1.0, string c = "red") { radius = r; color = c; }46 for any other inputs. void Author. setEmail(chuỗi email) { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }40, we assume that there is an Circle(double r = 1.0, string c = "red") { radius = r; color = c; }71 which is not the first or last character (there are other stricter email validation criteria). We use the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }39 class function Circle(double r = 1.0, string c = "red") { radius = r; color = c; }73 to find the position of the character Circle(double r = 1.0, string c = "red") { radius = r; color = c; }71, which returns a value of type Circle(double r = 1.0, string c = "red") { radius = r; color = c; }75 (typically same as Circle(double r = 1.0, string c = "red") { radius = r; color = c; }76). The function Circle(double r = 1.0, string c = "red") { radius = r; color = c; }73 returns a special constant Circle(double r = 1.0, string c = "red") { radius = r; color = c; }78 (which is typically set to -1) to indicate "not found"; 0 for the first character and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }79 for the last character (where Circle(double r = 1.0, string c = "red") { radius = r; color = c; }39's function Circle(double r = 1.0, string c = "red") { radius = r; color = c; }81 returns the length of the string). TestAuthor. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }33 Sách được viết bởi Tác giả - Sử dụng Thành viên dữ liệu "Đối tượng"Let's design a Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 class. Giả sử rằng một cuốn sách được viết bởi một và chỉ một tác giả. The Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 class (as shown in the class diagram) contains the following members
The hallow diamond shape in the class diagram denotes aggregation (or has-a) association relationship. That is, a Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 instance has one (and only one) Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 instance as its component Header File - Book. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }72 #include "Author. h" Circle(double r = 1.0, string c = "red") { radius = r; color = c; }013" header, as we use the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 class in this class Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82. riêng tư. Circle(double r = 1.0, string c = "red") { radius = r; color = c; }02 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }87 là một thể hiện của lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36, được định nghĩa trước đó. Implementation File - Book. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }37 Sách. Book(string name, Author author, double price, int qtyInStock) Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36, and pass the instance into the constructor. We use member initializer list to initialize data members Circle(double r = 1.0, string c = "red") { radius = r; color = c; }38 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }87. We call setters in the body, which perform input validation to set the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }89 and Circle(double r = 1.0, string c = "red") { radius = r; color = c; }91. The body is run after the member initializer list. The Circle(double r = 1.0, string c = "red") { radius = r; color = c; }024 invokes the default copy constructor of the Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 class, which performs memberwise copy for all the data members. Object data member shall be constructed via the member initializer list, not in the body. Otherwise, the default constructor will be invoked to construct the object. Sách trống. setPrice(giá gấp đôi) { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }89 validates the given input. Sách chuỗi. getAuthorName() const { Circle(double r = 1.0, string c = "red") { radius = r; color = c; }027 của thành viên dữ liệu Circle(double r = 1.0, string c = "red") { radius = r; color = c; }87, trả về tên tác giả của phiên bản Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 này. TestBook. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }15 Trình tạo bản sao mặc địnhThe initializer Circle(double r = 1.0, string c = "red") { radius = r; color = c; }024 in the constructor invokes the so-called copy constructor. Một hàm tạo bản sao tạo một thể hiện mới bằng cách sao chép thể hiện đã cho của cùng một lớp. Nếu bạn không cung cấp một hàm tạo bản sao trong lớp của mình, thì C++ sẽ cung cấp một hàm tạo bản sao mặc định, hàm tạo này sẽ xây dựng một đối tượng mới thông qua bản sao thành viên. Ví dụ, đối với lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36, hàm tạo bản sao mặc định do trình biên dịch cung cấp như sau Pass-by-Reference for Objects Function Parameters Author and stringBy default, objects are pass-by-value into functions. Nghĩa là, một bản sao được tạo và chuyển vào hàm, thay vì bản gốc. Pass-by-value for huge objects depicts performance due to the overhead of creating a clone copy Thay vào đó, chúng ta có thể truyền một đối tượng vào hàm theo tham chiếu, thông qua khai báo tham chiếu ( Circle(double r = 1.0, string c = "red") { radius = r; color = c; }032) trong danh sách tham số. If we do not intend to modify the object inside the function (with side effect to the original copy), we set it as Circle(double r = 1.0, string c = "red") { radius = r; color = c; }198 Trong lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82, các thành viên dữ liệu của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }39 và Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 là các đối tượng. Lớp Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 đã được định nghĩa trước đó; . Thay vì đưa " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }041" vào tiêu đề (đây là một cách làm không tốt vì câu lệnh này sẽ được đưa vào tất cả các tệp sử dụng tiêu đề này), chúng ta sẽ sử dụng toán tử phân giải phạm vi và gọi nó là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }042 Let's modify our Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 class to illustrate pass-by-reference (for performance) Author. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }39 Program Notes
Tác giả. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }76 Program Notes
Sách. hCircle(double r = 1.0, string c = "red") { radius = r; color = c; }77 Program Notes
Sách. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }37
Test Driver - TestBook. cppCircle(double r = 1.0, string c = "red") { radius = r; color = c; }79 Trong chương trình thử nghiệm ở trên, một thể hiện của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }36 có tên là Circle(double r = 1.0, string c = "red") { radius = r; color = c; }9 được xây dựng (ở Dòng 8). Thể hiện này được chuyển bằng tham chiếu vào hàm tạo của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 (Dòng 12) để tạo thể hiện của Circle(double r = 1.0, string c = "red") { radius = r; color = c; }82 Circle(double r = 1.0, string c = "red") { radius = r; color = c; }073 Bản tóm tắtTất cả các mã trong phiên bản ví dụ này (sử dụng tham chiếu) hoàn toàn giống với phiên bản trước (không sử dụng tham chiếu), ngoại trừ các tham số hàm đối tượng được đánh dấu bằng " Circle(double r = 1.0, string c = "red") { radius = r; color = c; }074" (e. g. , Circle(double r = 1.0, string c = "red") { radius = r; color = c; }075, Circle(double r = 1.0, string c = "red") { radius = r; color = c; }076). This eliminates the creation of temporary clone object as in the pass-by-value, which improves the performance. Take note that the constructor actually invokes the copy constructor to make a copy for its data member, instead of referencing the copy provided by the caller Is C# 100 objectC# hoàn toàn là OOP nhưng không HOÀN TOÀN là OOP . Đầu tiên, nó hoàn toàn là OOP vì mọi thứ đều là đối tượng. C# không phân biệt giữa kiểu nguyên thủy và kiểu đối tượng như trong Java. Do đó, int là một đối tượng, không phải là kiểu nguyên thủy.
Là C hoàn toàn đối tượngC là ngôn ngữ hướng thủ tục. Nó không hỗ trợ các tính năng lập trình hướng đối tượng (OOP) như đa hình, đóng gói và lập trình kế thừa.
C++ có phải là đối tượng 100 phần trăm khôngĐây không phải là ngôn ngữ hướng đối tượng độc quyền, mà còn là ngôn ngữ chức năng và thủ tục. Mặc dù có thể được coi là ngôn ngữ OOP, nhưng C++ không phải là ngôn ngữ hướng đối tượng thuần túy .
C có cấu trúc hay đối tượngNgôn ngữ C và Pascal là hai ngôn ngữ lập trình cấu trúc phổ biến . Trong lập trình có cấu trúc C, người dùng có thể tạo các hàm do người dùng định nghĩa của riêng mình. Chức năng chính gọi các chức năng khác. Nó chỉ ra việc thực hiện chương trình. |