Có thể làm cho các hàm thành viên của tôi final
như trong Java, sao cho các lớp dẫn xuất không thể ghi đè chúng?Làm thế nào để xác định các hàm thành viên 'cuối cùng' cho một lớp
Trả lời
Rất có thể thực tế là hành vi mặc định. I E. nếu bạn không khai báo các cá thể lớp của bạn một cách rõ ràng là virtual
, chúng không thể là overridden trong các lớp con (chỉ hidden, một trường hợp khác - và hầu như luôn luôn sai).
C++ phiên bản thứ ba hiệu quả, mục 36 đề cập chi tiết đến điều này. Hãy xem xét
class B {
public:
virtual void vf();
void mf();
virtual void mf(int);
...
};
class D: public B {
public:
virtual void vf(); // overrides B::vf
void mf(); // hides B::mf; see Item33
...
};
D x; // x is an object of type D
B *pB = &x; // get pointer to x
D *pD = &x; // get pointer to x
pD->vf(); // calls D::mf, as expected
pB->vf(); // calls D::mf, as expected
pD->mf(); // calls D::mf, as expected
pB->mf(); // calls B::mf - surprise!
pD->mf(1); // error - D::mf() hides B::mf(int)!
pB->mf(1); // calls B::mf(int)
Vì vậy, đây không phải là cách chính xác final
hoạt động trong Java, nhưng bạn chỉ có thể thực hiện việc này với C++. Một cách khác có thể là ngăn chặn phân lớp hoàn toàn. Giải pháp kỹ thuật, nhưng không tốt đẹp cho việc này là khai báo tất cả các nhà xây dựng của bạn private
(và cung cấp một phương thức nhà máy tĩnh nếu bạn muốn cho phép tạo ra lớp của bạn, tất nhiên).
nếu tôi không hiểu lầm, thì 'Ghi đè' là ẩn bản sao của lớp cơ sở, rất có thể trong trường hợp này. Điều tôi muốn là bắt buộc các lớp dẫn xuất luôn sử dụng/gọi hàm sao chép của lớp cơ sở. – Hemant
@Hemant, xem các liên kết và ví dụ mã tôi đã thêm. –
Tôi không biết Java, nhưng từ những gì tôi nghe tôi nghĩ trong Java bạn thậm chí không thể khai báo 'D :: mf()'. – sbi
Kiểm tra this từ Bjarne (Tôi có thể ngăn không cho người bắt nguồn từ lớp học của tôi?)
Trên thực tế nó là có thể nếu bạn đang sử dụng MSVC. Có một từ khóa sealed
. Đây là một số example from msdn.
C++ 11 cho biết thêm một từ khóa theo ngữ cảnh final
để hỗ trợ này:
class B
{
public:
virtual void foo() final;
};
class D : B
{
public:
virtual void foo(); // error: declaration of 'foo' overrides a 'final' function
};
final
được hỗ trợ trong GCC 4.7 và Clang 3.0. Và như Sergius ghi chú trong câu trả lời của mình, MSVC++ hỗ trợ nó (với chính tả sealed
), kể từ MSVC++ 2005. Vì vậy, nếu bạn đóng gói trong một vĩ mô nhỏ và thiết lập nó tùy thuộc vào trình biên dịch của bạn, bạn có thể được trên con đường của bạn với điều này. Chỉ cần đảm bảo rằng bạn thực sự là là sử dụng trình biên dịch như vậy ít nhất mỗi lần như vậy, vì vậy bạn sẽ sớm phát hiện bất kỳ lỗi nào.
Chuẩn C++ 11 mới hiện hỗ trợ phần ghi đè rõ ràng và chức năng cuối cùng của thành viên!
- 1. Làm thế nào để bạn sử dụng hàm tạo không mặc định cho một thành viên?
- 2. Làm thế nào để bạn sử dụng CreateThread cho các hàm là thành viên lớp?
- 3. Các tham chiếu không xác định đối với các hàm thành viên của một mẫu lớp
- 4. Điểm thành viên tham chiếu lớp cho thành viên khác trong cùng một lớp
- 5. chuyên môn mẫu cho các hàm thành viên tĩnh; làm thế nào để?
- 6. Hàm băm cho lớp do người dùng xác định. Làm thế nào để kết bạn? :)
- 7. Chỉ định một hàm thành viên của lớp làm bạn của một lớp khác?
- 8. Làm thế nào để kết hợp các hàm không phải thành viên với một lớp trong Doxygen?
- 9. 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?
- 10. Làm cách nào để chuyển một hàm thành viên của lớp như một cuộc gọi lại?
- 11. Làm cách nào để xác định và đặt cho thành viên dữ liệu mảng?
- 12. Tại sao các thành viên enum phủ định được liệt kê cuối cùng bởi foreach?
- 13. Thành viên được tính cho trẻ cuối cùng trong các tham số không theo thời gian?
- 14. Lớp con trỏ hàm thành viên
- 15. Tại sao các hàm thành viên của lớp đổ bóng các hàm miễn phí có cùng tên?
- 16. Trong golang, làm thế nào để xác định URL cuối cùng sau một loạt các chuyển hướng?
- 17. Làm thế nào để ẩn các thành viên tư nhân của một lớp học?
- 18. Python phân biệt hàm gọi lại là thành viên của một lớp như thế nào?
- 19. Làm thế nào để xác định một lớp trong lớp riêng tư khác trong C++
- 20. Làm thế nào để bạn vượt qua một con trỏ hàm thành viên?
- 21. Khi nào các hàm thành viên đặc biệt của một lớp mẫu được khởi tạo?
- 22. Xóa thành viên cuối cùng của std :: set
- 23. Tại sao một lớp không thể có cùng tên cho một hàm và một thành viên dữ liệu?
- 24. Xác định một hàm thành viên như một callback trong C++ 11
- 25. Làm thế nào để đăng ký con trỏ hàm thành viên lớp cơ sở với lớp cơ sở
- 26. C++ xác định một biến thành viên liên tục bên trong constructor lớp
- 27. std :: bind() - ing một hàm thành viên được bảo vệ cơ sở từ hàm thành viên của lớp dẫn xuất
- 28. Tại sao xác định các thành viên riêng dưới các thành viên công khai trong C++?
- 29. Làm thế nào để vượt qua một thành viên cấu trúc như một con trỏ trong một hàm
- 30. Làm thế nào để chuyên thành viên của lớp mẫu với tham số mẫu mẫu
Câu hỏi thú vị để hỏi trong cuộc phỏng vấn ... vì câu trả lời là không làm gì cả. (Tôi tin.) – Stephen
Không có chức năng đặc biệt nào trong C++ tránh ghi đè, chỉ cần khai báo ảo và ghi đè. – ratty
Câu hỏi không rõ ràng. Rằng bạn băn khoăn rằng nó đã ám chỉ đến tâm trí của tôi rằng bạn đang nói về các hàm ảo, trong trường hợp đó câu trả lời là không: một lớp bắt nguồn từ bất kỳ lớp nào có hàm ảo được chỉ định trong tổ tiên có thể ghi đè hàm. Như những người khác đã chỉ ra, sans "ảo", tất cả các chức năng không thể được ghi đè. Tôi không biết Java, vì vậy tôi không chắc chắn những gì nó cho phép khi .... –