Câu trả lời được chấp nhận giải thích điều này cho các chức năng riêng tư ảo , nhưng điều đó chỉ trả lời một khía cạnh cụ thể của câu hỏi, hạn chế hơn đáng kể so với những gì OP yêu cầu. Vì vậy, chúng ta cần phải viết lại: Tại sao chúng ta bắt buộc phải khai báo các hàm riêng không ảo trong các tiêu đề?
Một câu trả lời khác gọi thực tế là các lớp phải được khai báo trong một khối - sau đó chúng được niêm phong và không thể thêm vào. Đó là những gì bạn đang làm bằng cách bỏ qua để khai báo một phương thức riêng tư trong tiêu đề sau đó cố gắng xác định nó ở nơi khác. Điểm hay. Tại sao một số người dùng của lớp có thể tăng nó theo cách mà những người dùng khác không thể quan sát? Các phương thức riêng tư là một phần của nó và không loại trừ khỏi điều này. Nhưng sau đó bạn hỏi tại sao chúng được bao gồm, và nó có vẻ hơi tự nhiên. Tại sao người dùng lớp phải biết về họ? Nếu chúng không hiển thị, người dùng không thể thêm bất kỳ và xin chào.
Vì vậy, tôi muốn cung cấp một câu trả lời rằng, thay vì chỉ bao gồm các phương thức riêng tư theo mặc định, cung cấp các điểm cụ thể có lợi cho việc hiển thị chúng cho người dùng. Một lý do cơ học cho các chức năng riêng tư không ảo yêu cầu khai báo công khai được đưa ra trong Herb Sutter's GotW # 100 về thành ngữ Pimpl như là một phần của lý do căn bản của nó. Tôi sẽ không nói về Pimpl ở đây, vì tôi chắc rằng tất cả chúng ta đều biết về nó. Nhưng đây là bit có liên quan:
Trong C ++, khi mọi thứ trong định nghĩa lớp tệp tiêu đề thay đổi, tất cả người dùng của lớp đó phải được biên dịch lại - ngay cả khi thay đổi duy nhất là đối với các thành viên lớp riêng mà người dùng của lớp thậm chí không thể truy cập. Điều này là do mô hình xây dựng của C ++ dựa trên sự bao gồm văn bản và bởi vì C ++ giả định rằng người gọi biết hai điều chính về một lớp có thể bị ảnh hưởng bởi các thành viên tư nhân:
- Kích thước và bố cục : [của các thành viên và chức năng ảo - tự giải thích và tuyệt vời cho hiệu suất, nhưng không phải tại sao chúng tôi ở đây]
- Hàm : Mã gọi phải có khả năng giải quyết các cuộc gọi đến các chức năng thành viên của lớp, bao gồm các hàm riêng không thể truy cập quá tải với các hàm không bí mật - nếu chức năng riêng phù hợp hơn, mã gọi sẽ không thể biên dịch. (C ++ đã đưa ra quyết định thiết kế có chủ ý để thực hiện giải quyết quá tải trước khi kiểm tra khả năng truy cập vì lý do an toàn. Ví dụ, người ta cảm thấy rằng việc thay đổi khả năng truy cập của một chức năng từ riêng tư sang công cộng không nên thay đổi ý nghĩa của mã gọi hợp pháp.)
Tất nhiên, Sutter là một nguồn cực kỳ đáng tin cậy với tư cách là thành viên của Ủy ban, vì vậy anh ta biết "một quyết định thiết kế có chủ ý" khi anh ta nhìn thấy. Và ý tưởng yêu cầu tuyên bố công khai các phương thức riêng tư như một cách để tránh thay đổi ngữ nghĩa hoặc vô tình bị hỏng khả năng tiếp cận sau này có lẽ là lý do thuyết phục nhất. Rất may, vì toàn bộ điều này dường như khá vô nghĩa trước đây!