Đọc rằng bạn có thể có final virtual functions trong C++ 0x Tôi hơi bối rối. Sự khác biệt khi bỏ qua cả hai công cụ sửa đổi ở vị trí đầu tiên là gì?chức năng ảo cuối cùng trong C++ 0x
Trả lời
Sự khác biệt xảy ra không phải là cơ sở sử dụng nó, mà là nguồn gốc.
class Base {
virtual void foo() = 0;
};
class Derived : Base {
void foo() {}
// Still virtual because it's virtual in base- no way to "un-virtual" it
virtual void foo() final {}
// Now un-overridable.
};
Hãy nghĩ rằng nó không phải là ngăn chặn ghi đè, nhưng ngăn ngừa ghi đè "bất kỳ" nào khác.
Cảm ơn! Nó không rõ ràng với tôi, rằng ảo được thực hiện thông qua toàn bộ hệ thống phân cấp. –
Khi tôi lần đầu tiên đi qua việc sử dụng các từ khóa final
kết hợp với virtual
trong C++, tôi đã tự hỏi điều tương tự:
Nếu tuyên bố một phương pháp
virtual
làm cho nó thừa kế và overridable, và tuyên bố một phương phápfinal
ngăn không cho phương thức đó bị ghi đè, không khai báo phương thức cả hai là một mâu thuẫn?
Tôi nghĩ rằng hiện tại accepted answer cho câu hỏi này là tốt, nhưng tôi muốn xây dựng dựa trên nó nhiều hơn một chút dựa trên những gì tôi thấy.
Hãy xem xét các lớp sau đây:
class A {
public:
void hide_me();
virtual void override_me();
virtual void cant_override_me() final;
};
Điều quan trọng cần nhận ra là ba lời tuyên bố phương pháp đều khác biệt và ý nghĩa khác nhau.
Đầu tiên:
void hide_me();
là không ảo và do đó, theo định nghĩa, không thể được ghi đè.
Thứ ba:
virtual void cant_override_me() final;
được khai báo final
, và do đó không thể được ghi đè, cũng theo định nghĩa.
Sự khác biệt là kể từ khi hide_me
là không ảo, trọng nó là unapplicable, trong khi bạn có thể nghĩ cant_override_me
như đủ điều kiện để được ghi đè (vì nó là virtual
,) nhưng nó cũng đã trọng bị vô hiệu hóa do công cụ sửa đổi final
. Nói cách khác, ghi đè không áp dụng cho các phương thức không được khai báo là virtual
, nhưng nó áp dụng cho các phương thức virtual
, bạn không thể ghi đè chúng nếu chúng cũng được khai báo final
.
Bây giờ hãy xem xét một lớp trẻ:
class B: public A {
public:
void hide_me(); // this hide's A's definition of "hide_me()"; this is not overriding.
void override_me(); // implicit "virtual"
//void cant_override_me(); // implicit "virtual"; compilation fails
};
Bạn thể xác định lại hide_me()
cho lớp B
, nhưng điều này chỉ là quá tải hoặc hiding, vì thế mà tên hàm. B
vẫn có thể truy cập phương thức hide_me
của A
qua A::hide_me()
, nhưng một người khác có tham chiếu đến B
được khai báo là B
, tức là:
B *my_b = new B();
phải truy cập A
's bây giờ ẩn nghĩa về hide_me
qua my_b->A::hide_me()
.
Bạn không thể cung cấp định nghĩa lại cant_override_me()
trong B
.
Là một ví dụ đầy đủ, đây là một định nghĩa lại nhẹ của chương trình để giúp minh họa cho những gì đang xảy ra:
#include <cstdio>
class A {
public:
inline void hide_me() {
printf("a hide_me\n");
}
virtual void override_me();
virtual void cant_override_me() final;
};
class B: public A {
public:
inline void hide_me() {
printf("b hide_me\n");
}
void override_me();
inline void foo() {
A::hide_me();
}
// can't override cant_override_me
};
void A::override_me() {
printf("a override_me\n");
}
void A::cant_override_me() {
printf("a cant_override_me\n");
}
void B::override_me() {
printf("b override_me\n");
}
int main (int argc, char *argv[]) {
A *a = new A();
A *ab = new B();
B *b = new B();
a->hide_me();
ab->hide_me();
b->hide_me();
b->A::hide_me();
printf("---\n");
a->override_me();
ab->override_me();
b->override_me();
b->A::override_me();
}
Các đầu ra chương trình
a hide_me
a hide_me
b hide_me
a hide_me
---
a override_me
b override_me
b override_me
a override_me
- 1. Xóa chức năng ảo trong C++ 0x
- 2. C++: Các chức năng ảo cần gọi cùng một mã?
- 3. C++ chức năng ghi đè ảo cùng tên
- 4. C++ ảo Const Chức năng
- 5. Chức năng Unicode mới nào có trong C++ 0x?
- 6. Hành vi chức năng ảo trong C++
- 7. C++ nhớ bảng chức năng ảo tốn
- 8. Thực hiện chức năng cuối cùng
- 9. Chức năng ảo Mimic (thuần) ảo như C#
- 10. chức năng ảo const vs chức năng ảo không const
- 11. C++ "chức năng ảo nhưng không có hàm hủy ảo"
- 12. Ghi đè các chức năng ảo công cộng với các chức năng riêng tư trong C++
- 13. chức năng không đồng bộ gọi C++ 0x
- 14. chức năng excel để tìm số cuối cùng trong cột
- 15. Thừa kế chức năng ảo
- 16. chức năng ảo nội tuyến
- 17. Chức năng ảo thuần túy nằm ở đâu trong C++?
- 18. C++ chức năng ảo không được gọi trong lớp con
- 19. typecasting với các chức năng ảo
- 20. chức năng thành viên C++ override ảo và quá tải cùng lúc
- 21. Tách chức năng - tránh không gian trống cuối cùng
- 22. Python chuỗi chức năng để dải dấu phẩy cuối cùng
- 23. Chức năng ảo có ghi đè lên một hàm không phải ảo trong cùng một lớp cơ sở không?
- 24. Overhead của kế thừa C++ không có chức năng ảo
- 25. Ghi đè rõ ràng chức năng ảo
- 26. Câu hỏi với các chức năng ảo
- 27. Gọi chức năng ảo từ bảng V
- 28. Chức năng ảo có thể bị ghi đè bởi một chức năng phi ảo không?
- 29. gcc 4.7.2 lỗi chức năng ảo
- 30. Có C++ 0x cho phép decltype() trong chữ ký chức năng?
xem xét, trong ví dụ này, nếu 'Base' được kế thừa từ một lớp khác khai báo phương thức 'f' gốc ban đầu. –