2012-03-07 23 views
15

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ú ý:

  1. 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ư?

Trả lời

11

Câu trả lời khá đơn giản:

Design Patterns dates from 1994. Tại thời điểm này C++ vẫn đang phát triển mạnh mẽ vào ngôn ngữ mà chúng ta biết ngày nay - tiêu chuẩn trước đó đã được hoàn thành vào năm 1998! Các trình biên dịch bị lỗi và không hỗ trợ các tính năng quan trọng mà chúng tôi hiện đang cho phép.

Nhưng quan trọng hơn, nhiều điều chưa được phát hiện (đặc biệt là bởi các lập trình viên chính thống). Lập trình siêu lập trình mẫu, toàn bộ chỉ được “vấp” around the same time.

Tôi rất nghi ngờ rằng điều này cũng đúng với các chức năng ảo riêng tư: GoF đơn giản là không biết rằng đây là C++ hợp pháp. Hoặc nếu có, nó đã không tự thiết lập như một quy ước. Trên thực tế, hầu hết mã C++ được coi là "tốt" vào năm 1994 sẽ được coi là quá phức tạp và dễ bị lỗi ngày nay, thậm chí không cần tính đến C++ 11.

+3

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. –

+1

@ 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 ... –

+0

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. –

Các vấn đề liên quan