Theo tôi hiểu, việc giới thiệu override
từ khóa trong C ++ 11 không gì khác hơn là kiểm tra để đảm bảo rằng hàm được triển khai là override
ing của một virtual
hàm trong lớp cơ sở.
Là nó?
Theo tôi hiểu, việc giới thiệu override
từ khóa trong C ++ 11 không gì khác hơn là kiểm tra để đảm bảo rằng hàm được triển khai là override
ing của một virtual
hàm trong lớp cơ sở.
Là nó?
Câu trả lời:
Đó thực sự là ý tưởng. Vấn đề là bạn rõ ràng về ý của bạn, do đó có thể chẩn đoán lỗi im lặng:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Các mã trên biên dịch, nhưng không phải là những gì bạn có thể có nghĩa (lưu ý thiếu const
). Nếu bạn nói thay vào đó, virtual int foo() override
thì bạn sẽ gặp lỗi trình biên dịch rằng trên thực tế chức năng của bạn không ghi đè bất cứ điều gì.
override
tính năng mới "khắc phục" điều này; bạn phải nhớ sử dụng nó, giống như bạn nên nhớ để viết const
;)
explicit
các định nghĩa lớp không biến nó thành C ++ 11. Huh.
explicit
định nghĩa lớp sẽ làm gì? Chưa bao giờ nghe về điều đó cả.
override
khi có ý định thực hiện) có nhiều khả năng hơn là ghi nhớ các trường hợp góc, nghĩa là không có tính tổng quát trong việc sao chép các chức năng của các nguyên mẫu khác nhau, chỉ có sự bất thường như thiếu const
hoặc viếtchar
thay vì int
vv
override
specifier được đề cập trong câu trả lời này , đó là tương lai hơn là ngay lập tức. Câu trả lời cho thấy rằng, giữ override
với virtual
phương pháp. Trong tương lai khi một người thay đổi nhầm chữ ký, tính hữu dụng của nó sẽ xuất hiện.
Trích dẫn Wikipedia:
Mã định danh đặc biệt ghi đè có nghĩa là trình biên dịch sẽ kiểm tra (các) lớp cơ sở để xem liệu có một hàm ảo có chữ ký chính xác này không. Và nếu không có, trình biên dịch sẽ báo lỗi.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Chỉnh sửa (cố gắng cải thiện một chút câu trả lời):
Khai báo một phương thức là "ghi đè" có nghĩa là phương thức đó được dự định viết lại một phương thức (ảo) trên lớp cơ sở. Phương thức ghi đè phải có cùng chữ ký (ít nhất là đối với các tham số đầu vào) như phương thức mà nó dự định viết lại.
Tại sao điều này là cần thiết? Vâng, hai trường hợp lỗi phổ biến sau đây được ngăn chặn:
một loại sai trong một phương thức mới. Trình biên dịch, không biết rằng nó đang có ý định viết một phương thức trước đó, chỉ cần thêm nó vào lớp như một phương thức mới. Vấn đề là phương thức cũ vẫn còn đó, phương thức mới được thêm vào chỉ là quá tải. Trong trường hợp này, tất cả các cuộc gọi hướng tới phương thức cũ sẽ hoạt động như trước đây, mà không có bất kỳ thay đổi nào trong hành vi (đó sẽ là mục đích chính của việc viết lại).
người ta quên khai báo phương thức trong siêu lớp là "ảo", nhưng vẫn cố gắng viết lại nó trong một lớp con. Mặc dù điều này rõ ràng sẽ được chấp nhận, nhưng hành vi sẽ không chính xác như dự định: phương thức này không phải là ảo, vì vậy việc truy cập thông qua con trỏ tới siêu lớp sẽ kết thúc bằng cách gọi phương thức (siêu lớp ') cũ thay vì phương thức (lớp con') mới.
Thêm "ghi đè" rõ ràng làm rõ điều này: thông qua điều này, người ta đang nói với trình biên dịch rằng có ba điều đang mong đợi:
Nếu bất kỳ trong số này là sai, thì một lỗi được báo hiệu.
* lưu ý: tham số đầu ra đôi khi khác nhau, nhưng loại liên quan. Đọc về biến đổi covariant và contravariant nếu quan tâm.
Tìm thấy " ghi đè " là hữu ích khi ai đó cập nhật chữ ký phương thức ảo lớp cơ sở, chẳng hạn như thêm một tham số tùy chọn nhưng quên cập nhật chữ ký phương thức lớp dẫn xuất. Trong trường hợp đó, các phương thức giữa lớp cơ sở và lớp dẫn xuất không còn quan hệ đa hình nữa. Nếu không có khai báo ghi đè, thật khó để tìm ra loại lỗi này.
override
là một cách tuyệt vời để khám phá những vấn đề như vậy, nhưng phạm vi kiểm tra đơn vị tốt cũng sẽ giúp ích.
Vâng, đây là như vậy. Đó là một kiểm tra để đảm bảo rằng người ta không thử ghi đè và làm hỏng nó thông qua một chữ ký bị lừa. Đây là một trang Wiki giải thích điều này một cách chi tiết và có một ví dụ minh họa ngắn:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Dự thảo tiêu chuẩn C ++ 17
Sau khi xem qua tất cả các override
lần truy cập vào bản nháp tiêu chuẩn C ++ 17 N4659 , tài liệu tham khảo duy nhất tôi có thể tìm thấy cho override
định danh là:
5 Nếu một chức năng ảo được đánh dấu bằng ghi đè virt-specifier và không ghi đè chức năng thành viên của lớp cơ sở, chương trình sẽ không được định dạng. [ Thí dụ:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- ví dụ kết thúc]
Vì vậy, tôi nghĩ rằng có thể thổi tung các chương trình sai thực sự là hiệu ứng duy nhất.