Trong trường hợp nào chúng ta sẽ khai báo chức năng thành viên như một 'chức năng bạn bè'? Mục đích chính xác của 'chức năng người bạn' nào là bất chấp khái niệm trung tâm về 'đóng gói' của OOP phục vụ?Trong trường hợp nào thì một người nên khai báo một thành viên có chức năng một người bạn?
Trả lời
Bạn sẽ sử dụng một hàm bạn bè cho cùng một loại lý do mà bạn sẽ sử dụng một lớp bạn bè, nhưng trên cơ sở thành viên (chứ không phải toàn bộ lớp) cơ sở. Một số giải thích tốt là ở số this thread.
Trong khi chức năng và lớp học của bạn bè vi phạm đóng gói, chúng có thể hữu ích trong một số trường hợp. Ví dụ: bạn có thể muốn cho phép khai thác thử nghiệm truy cập vào nội dung lớp học để cho phép bạn thực hiện kiểm tra whitebox. Thay vì mở toàn bộ lớp học để khai thác thử nghiệm, bạn có thể mở ra một chức năng cụ thể truy cập vào các bộ phận bên trong được yêu cầu bởi dây nịt thử nghiệm. Trong khi điều này vẫn vi phạm đóng gói, nó ít rủi ro hơn việc mở toàn bộ lớp học.
Cũng xem this article để biết thêm thông tin về các lớp và chức năng của bạn bè.
Đôi khi mức độ bảo vệ công cộng/riêng tư/bảo vệ không đủ cho các tình huống thực tế. Vì vậy, do đó, chúng tôi đưa ra một mệnh đề nhỏ để giúp đỡ mà không phải làm cho các phương thức có thể truy cập công khai.
Cá nhân tôi sử dụng cách này giống như cách Java sử dụng cấp độ bảo vệ 'Gói'.
Nếu tôi có một lớp học trong cùng một gói cần truy cập, tôi sẽ xem xét sử dụng bạn bè. Nếu nó là một lớp học trong một gói khác thì tôi sẽ tự hỏi tại sao trên trái đất này là lớp khác cần truy cập và nhìn vào thiết kế của tôi.
Xem C++ FAQ Lite:
Đôi khi bạn bè là cú pháp tốt hơn (ví dụ, trong lớp Fred, chức năng bạn cho phép tham số Fred là thứ hai, trong khi các thành viên cần nó để là người đầu tiên). Một cách sử dụng tốt các chức năng của bạn là các toán tử số học nhị phân. Ví dụ, aComplex + aComplex nên được định nghĩa là một người bạn chứ không phải là thành viên nếu bạn muốn cho phép aFloat + aComplex (các hàm thành viên không cho phép quảng cáo đối số bên trái, vì điều đó sẽ thay đổi lớp của đối tượng người nhận lời gọi hàm thành viên).
Chức năng và lớp học của bạn không vi phạm đóng gói khi bạn đang cố gắng xây dựng một giao diện trừu tượng hoặc phải trải qua nhiều lớp hoặc chức năng C++! Đó là lý do tại sao bạn được phát minh.
Các loại trường hợp này không xuất hiện thường xuyên, nhưng đôi khi bạn buộc phải triển khai một giao diện trừu tượng hoặc giao diện với các lớp và chức năng khác nhau. Ví dụ cổ điển đang triển khai một số loại lớp số phức. Các hàm toán tử không phải là thành viên được cung cấp tình bạn cho lớp số phức chính.
Tôi cũng nhớ khi thực hiện điều này khi lập trình với CORBA trong C++. CORBA buộc tôi phải có các lớp riêng biệt để thực hiện các công chức của Corba. Nhưng đối với một phần cụ thể của phần mềm của chúng tôi, tôi cần kết hôn với nhau như một giao diện. Tình bạn cho phép hai lớp này làm việc cùng nhau để cung cấp một dịch vụ liên tục cho một phần của phần mềm của chúng tôi.
Có khả năng đánh dấu một chức năng thành viên cụ thể trên một lớp khác với tư cách một người bạn trong lớp của bạn có vẻ xa lạ hơn, nhưng đó chỉ là cách kiểm soát chặt chẽ tình bạn. Thay vì cho phép toàn bộ lớp khác "vào" làm bạn của bạn, bạn chỉ cho phép một trong các chức năng truy cập thành viên của nó. Một lần nữa, điều này không phổ biến, nhưng rất hữu ích khi bạn cần.
Một điểm mà tôi thấy có liên quan: các lớp thành viên có quyền truy cập vào các phần riêng tư của lớp chứa. Điều này đôi khi có thể là một lựa chọn tốt hơn cho "người bạn".
class A
{
private:
int b;
public:
class MemberNotFriend {
public:
static void test() {
A a;
a.b = 0;
}
};
};
void test()
{
A::MemberNotFriend::test();
}
Đây là một đơn giản, ví dụ cụ thể về cách tôi đang sử dụng một hàm friend:
Tôi có một trò chơi trong đó mỗi đối tượng sprite lưu trữ thông tin của nó như X, Y vị trí như các thành viên tư nhân. Tuy nhiên, tôi muốn tách các đối tượng trò chơi khỏi hiển thị: đối tượng trò chơi không cần chi tiết chính xác về cách hiển thị. Một đối tượng trò chơi chỉ lưu trữ trạng thái trò chơi và trạng thái trò chơi này có thể được hiển thị theo một số cách khác nhau.
Do đó lớp đối tượng trò chơi có chức năng kết bạn: render(). Hàm render() được thực hiện bên ngoài lớp đối tượng trò chơi, nhưng nó có thể truy cập vào các vị trí bản ghi vị trí vị trí X, Y khi cần để hiển thị đối tượng trò chơi.
- 1. Tôi nên triển khai thành viên người dùng trong trang web MVC ASP.NET như thế nào?
- 2. Bạn có thể sử dụng sizeof một thành viên khi khai báo một thành viên khác không?
- 3. lớp người bạn chức năng bên trong một không gian tên
- 4. C++ chức năng người bạn nội tuyến có cùng tên với biến thành viên
- 5. Nhiệm vụ của thành viên trong một chức năng const
- 6. Khi nào bạn nên hạn chế khả năng truy cập vào một chức năng ảo trong một lớp dẫn xuất?
- 7. chức năng người bạn trong php?
- 8. Khi nào nên sử dụng chức năng thành viên tĩnh?
- 9. một lớp-key phải được khai báo khi tuyên bố một người bạn
- 10. Khi nào tôi nên sử dụng các chức năng không phải là thành viên không phải thành viên đối với các chức năng của thành viên?
- 11. Khai báo một chức năng ẩn danh trong stdClass mới
- 12. Chức năng thành viên tĩnh
- 13. Tại sao có thể đặt định nghĩa chức năng người bạn bên trong định nghĩa lớp?
- 14. lỗi: không có chức năng thành viên '__________' được khai báo trong lớp '_______'
- 15. Bạn có nên khai báo các enums bên trong hoặc bên ngoài một lớp học không?
- 16. Có nên đi theo chức năng của thành viên hoặc chức năng bạn bè khi chức năng được cho là thay đổi trạng thái của đối tượng không?
- 17. khai C chức năng trong một chức năng
- 18. làm thế nào để khai báo một lớp mẫu với tư cách một người bạn trong C++
- 19. 'Người dùng đang nhập chức năng của một tin nhắn' ...?
- 20. Move thế hệ chức năng thành viên
- 21. Báo cáo trường hợp/Chức năng giải mã trong Informatica
- 22. các chức năng 'người bạn' và << quá tải toán tử: Cách thích hợp để quá tải một toán tử cho một lớp là gì?
- 23. là có thể sử dụng QtConcurrent :: run() với một thành viên chức năng của một lớp
- 24. Khi nào một người nên sử dụng mô hình Diễn viên?
- 25. Làm cách nào để gọi một chức năng sau khi một người ngừng nhập?
- 26. Khi nào tôi nên phá vỡ một chức năng?
- 27. C++: Làm thế nào một hàm thành viên tĩnh công khai truy cập các biến thành viên cá thể riêng?
- 28. Làm thế nào để khai báo một từ điển có chức năng nội tuyến
- 29. Khai báo các tham số bên ngoài người khai báo
- 30. Có thể khai báo một loại tại phạm vi chức năng trong F # không?
+1 cho "không vi phạm". Tuy nhiên, nó là vô ích trong trường hợp của hầu hết các lớp số như phức tạp, hợp lý, ... –