Thuộc tính là cách hiện đại trong C ++ để chuẩn hóa mọi thứ nếu mã của chúng chạy trên các trình biên dịch khác nhau. Các thuộc tính được sử dụng để cung cấp một số thông tin bổ sung được sử dụng để thực thi điều kiện (ràng buộc), tối ưu hóa và tạo mã cụ thể nếu được yêu cầu.
Đây giống như một sổ tay hướng dẫn thông tin cho các trình biên dịch để thực hiện một số thực thi sẽ cải thiện hiệu suất của mã. Các thuộc tính được nhìn thấy lần đầu tiên trong C ++ 11 và là những phần quan trọng của ngôn ngữ lập trình kể từ đó, Ngoài ra, với mỗi phiên bản, một số bản sửa đổi liên tục được thực hiện để làm cho chúng trở nên mạnh mẽ hơn và tốt hơn.
Hãy xem cách chúng tôi có thể xác định các thuộc tính trong C ++
Đối với các phiên bản C ++ khác nhau, cú pháp để xác định các thuộc tính là khác nhau.
Cú pháp tạo thuộc tính trong c ++ 11 -
[[attribute-list]]
Cú pháp tạo thuộc tính trong c ++ 17 -
[[using attribute-namespace : attribute_list]]
Cú pháp tạo thuộc tính trong c ++ 20 (sẽ sớm được xuất bản) -
[[contract-attriubute-token contract-level-identifier : expression]]
Bạn có thể sử dụng nhiều thuộc tính với các biến, hàm, lớp.
Bây giờ, vì chúng ta đã biết các thuộc tính là gì, cách chúng hoạt động và cách chúng được định nghĩa. Hãy xem các thuộc tính tiêu chuẩn khác nhau có sẵn trong c ++.
Các thuộc tính được giới thiệu trong C ++ 11
noreturn - Thuộc tính này được sử dụng để cho trình biên dịch biết rằng hàm không trả về bất kỳ giá trị nào.
Cú pháp
[[noreturn]]
ví dụ
[[noreturn]] void f();
Hàm này sẽ không trả về bất kỳ giá trị nào, thậm chí không vô hiệu.
Thuộc tính noreturn, khi được sử dụng trong c ++, cho phép trình biên dịch trả về cảnh báo trong trường hợp có điều gì đó sai xảy ra và luồng không quay trở lại mã gọi, như trong trường hợp vòng lặp vô hạn hoặc bất kỳ lỗi nào.
carry_dependency - Điều này được sử dụng để xác định tất cả các phụ thuộc trong bản phát hành-tiêu thụ và cho phép trình biên dịch tối ưu hóa bằng cách không đi qua các hướng dẫn sử dụng bộ nhớ không cần thiết.
Cú pháp
[[carries_dependency]]
Điều này chủ yếu được sử dụng với việc khai báo các hàm hoặc tham số để khai báo các phần phụ thuộc.
không dùng nữa - Điều này được sử dụng để xác định một thực thể không dùng nữa trong mã. Việc sử dụng thực thể không dùng nữa này được cho phép nhưng bạn không nên sử dụng nó.
Cú pháp
[[deprecated]] [[deprecated (reason)]]
Lý do là một chuỗi cung cấp lý do tại sao khấu hao được thực hiện và cũng cung cấp một giải pháp thay thế cho thực thể không dùng nữa.
Các thực thể có thể không được dùng nữa là lớp, cấu trúc, liên hiệp, typedef-name, thành viên tĩnh, hàm, không gian tên, kiểu liệt kê.
dự đoán - Điều này được sử dụng để chỉ ra cho trình biên dịch biết rằng lỗi dự phòng từ trường hợp tiếp theo là có chủ ý, do đó trình biên dịch không cảnh báo lỗi dự phòng.
Cú pháp
[[fallthrough]]
Chỉ có thể sử dụng đường dự phòng với công tắc vì trường hợp tiếp theo được xác định cho nó.
Thẻ ghi chú - Điều này được sử dụng cho một hàm sẽ trả về một kiểu liệt kê sẽ được gọi từ biểu thức giá trị bị loại bỏ thay vì ép kiểu thành lệnh gọi void. Trình biên dịch cũng sẽ đưa ra cảnh báo cho nó.
Cú pháp
[[nodiscard]] [[nodiscard (reason)]] (added in C++ 20)
Lý do là một chuỗi được sử dụng để cung cấp lý do không loại bỏ kết quả và điều này sẽ được bao gồm trong c ++ 20.
có thể_unused - Điều này được sử dụng để yêu cầu trình biên dịch ngăn chặn hoặc loại bỏ cảnh báo được hiển thị trong trường hợp các thực thể không sử dụng.
Cú pháp
[[maybe_unused]]
Các thực thể có thể được khai báo có thể_unused là lớp, cấu trúc, liên hiệp, typedef-name, thành viên tĩnh, hàm, biến, kiểu liệt kê.
có thể, không chắc - Chúng được sử dụng để xác định thời tiết mà con đường thay thế có nhiều khả năng hơn hoặc ít hơn khả năng thực thi hiện tại.
Cú pháp
[[likely]] [[unlikely]]
Những điều này thường được áp dụng cho các thực thể làm thay đổi luồng chương trình như nhãn và câu lệnh.
no_unique_address - Điều này được sử dụng để xác định một thành viên dữ liệu không cần phải có một địa chỉ cụ thể. Nó thường được sử dụng trong trường hợp các thành viên dữ liệu không tĩnh xác định việc cấp phát bộ nhớ của họ là không cần thiết.
Cú pháp
[[no_unique_address]]
Điều này hữu ích khi trình biên dịch cần gán vị trí bộ nhớ giữa biến bình thường và biến no_unique_address, trình biên dịch sẽ ưu tiên biến trước đó.
Optimize_for_synchronized - Điều này được sử dụng để xác định rằng định nghĩa của hàm đã cho phải được tối ưu hóa cho lệnh gọi từ câu lệnh được đồng bộ hóa.
Cú pháp
[[optimize_for_synchronized]]
Hàm được định nghĩa làmize_for_synchronized sẽ tránh tuần tự hóa các khối được đồng bộ hóa.
mong đợi - Nó chỉ định các điều kiện bắt buộc đối với các đối số của một hàm để hàm được thực thi.
Cú pháp
[[expects : condition]]
điều kiện xác định một điều kiện cần được đáp ứng để chức năng được thực thi.
Đây là tất cả các thuộc tính được định nghĩa trong C ++ từ C ++ 11 đến C ++ 20. Bây giờ, hãy xem tại sao các thuộc tính này được sử dụng trong lập trình, tức là các thuộc tính được đề xuất giải quyết vấn đề gì?
-
Để thêm các ràng buộc vào mã - Trong nhiều trường hợp, các thuộc tính bổ sung ý nghĩa cho mã và làm cho mã hợp lệ hơn và giảm thêm nỗ lực.
-
Cung cấp thêm một số thông tin tối ưu hóa cho trình biên dịch - Một số thuộc tính như dự phòng, có khả năng, có thể sử dụng cung cấp thông tin cho trình biên dịch để thực hiện các tối ưu hóa cụ thể.
-
Đang thoát cảnh báo và lỗi - Đôi khi logic của lập trình viên đi ngược lại các quy tắc nghiêm ngặt của C ++. Đây là trường hợp một số thuộc tính phát huy tác dụng và giúp người dùng tránh hoặc ngăn chặn cảnh báo sắp xảy ra.