Từ Bè lũ bốn tên trên mẫu Template Method:Tại sao GoF khuyến cáo sử dụng các phương thức ảo được bảo vệ (như trái ngược với tư nhân) trong việc thực hiện Mẫu Phương thức Mẫu C++?
Ba vấn đề thực hiện là đáng chú ý:
- Sử dụng kiểm soát truy cập C++. Trong C++, các hoạt động nguyên thủy mà một cuộc gọi phương thức mẫu có thể được khai báo thành viên được bảo vệ. Điều này đảm bảo rằng chúng chỉ được gọi theo phương thức mẫu. Các hoạt động nguyên thủy phải được ghi đè được khai báo là thuần ảo. Phương thức mẫu không được ghi đè; do đó bạn có thể làm cho phương thức mẫu là một hàm thành viên không ảo.
"Điều này đảm bảo rằng chúng chỉ được gọi theo phương pháp mẫu". không đúng, phải không? Như các phương thức nguyên thủy (nếu một số là ảo thay vì ảo thuần túy chẳng hạn) cũng có thể được gọi từ một lớp dẫn xuất. Có đúng là chỉ khai báo các phương thức nguyên thủy riêng tư đảm bảo chúng chỉ được gọi bởi phương thức mẫu? Các phương thức ảo nguyên thủy riêng tư sau đó có thể vẫn được thực thi (hoặc reimplemented) trong các lớp con để cung cấp hành vi chuyên biệt được yêu cầu trong thuật toán được định nghĩa trong phương thức khuôn mẫu trong lớp cha.
Xem "tính ảo" từ Herb Sutter:
http://www.gotw.ca/publications/mill18.htm
đâu ông nói rằng:
Hướng dẫn # 2: thích làm cho các chức năng ảo tư nhân. Hướng dẫn # 3: Chỉ khi các lớp dẫn xuất cần phải gọi triển khai cơ sở của hàm ảo , hãy bảo vệ chức năng ảo.
Tôi không thấy bất kỳ yêu cầu nào trong mẫu Phương thức mẫu của GoF cho các lớp dẫn xuất để gọi triển khai lớp cơ sở của các hàm ảo, vậy tại sao Gang of Four khuyên bạn nên thực hiện các chức năng này chứ không phải riêng tư?
Quan điểm lịch sử ít nhiều đúng --- vào năm 1995, tôi không nghĩ rằng nó thậm chí còn xảy ra với hầu hết các lập trình viên C++ mà bạn có thể ghi đè lên một hàm riêng tư.(Và các chức năng ảo trong 'std :: streambuf' được bảo vệ, không riêng tư.) Tuy nhiên, ngay cả ngày hôm nay, tôi nghĩ rằng có một số người thích' bảo vệ' hơn là 'riêng tư 'cho các chức năng như vậy. Họ chắc chắn phải được biết đến với lớp dẫn xuất, và đối với những người đó, 'private' có nghĩa là private, ít nhất là đối với người đọc của con người, nếu không phải trình biên dịch. –
@ James Tôi có thể chứng thực điều đó ... cho đến gần đây tôi đã không biết rằng điều này là hợp pháp, và thấy nó rất khó hiểu lúc đầu tiên ... –
Cảm ơn. Tôi nghi ngờ đây là câu trả lời nhưng tôi đã có C++ Common Knowledge (2005) của Stephen Dewhurst trước khi đặt câu hỏi và nó nêu lên sự nghi ngờ của tôi rằng có điều gì đó nhiều hơn đối với bảo vệ/tư nhân mà tôi đã bỏ lỡ. Chương của nó trên Phương thức mẫu đề cập rằng nó "thường" được triển khai để gọi các hàm ảo được bảo vệ, nó sẽ tiếp tục sử dụng trong ví dụ mã. Nó không đưa ra bất kỳ đề cập nào về vấn đề riêng tư so với được bảo vệ cho các hàm nguyên thủy được gọi bằng phương thức mẫu khác. –