2010-11-05 36 views
15

Trong mã C khác nhau, tôi thấy hằng số được định nghĩa như thế này:hằng #defining trong C++

#define T 100 

Trong khi trong C++ ví dụ, đó là hầu như luôn luôn:

const int T = 100; 

Đó là sự hiểu biết của tôi rằng trong trường hợp đầu tiên, bộ tiền xử lý sẽ thay thế mọi thể hiện của T bằng 100. Trong ví dụ thứ hai, T thực sự được lưu trữ trong bộ nhớ.

Được coi là thực hành lập trình không tốt để #define hằng số trong C++?

+0

'T' không nhất thiết sẽ sử dụng bất kỳ bộ nhớ nào sau khi biên dịch chương trình. – GManNickG

Trả lời

28

Được coi là thực hành lập trình không tốt để #define hằng số trong C++?

Có, vì tất cả các macro (được định nghĩa là #define s) nằm trong một vùng tên duy nhất và chúng có hiệu lực ở mọi nơi. Các biến, bao gồm const biến đủ điều kiện, có thể được đóng gói trong các lớp và không gian tên.

Macro được sử dụng trong C vì trong C, một biến số const không thực sự là hằng số, nó chỉ là một biến không thể sửa đổi được. Biến số const -qualified không thể xuất hiện trong một biểu thức liên tục, vì vậy nó không thể được sử dụng như là một kích thước mảng, ví dụ.

Trong C++, một đối tượng -qualified const được khởi tạo với một biểu thức hằng số (như const int x = 5 * 2;) một hằng số và có thể được sử dụng trong một biểu thức hằng số, vì vậy bạn có thể và nên sử dụng chúng.

+0

Thực ra, bit cuối cùng không đúng. 'const int x = rand();' là hợp pháp, nhưng sau đó có thể không được sử dụng như một tham số mảng hoặc mẫu. – MSalters

+0

@MSalters: Rất tiếc; lỗi của tôi. Sửa chữa để thêm rằng một đối tượng đủ điều kiện const cần phải được khởi tạo với một biểu thức liên tục để nó có thể sử dụng được trong một biểu thức liên tục. Cảm ơn vì sự đúng đắn của bạn. –

2

Có. Ít nhất, sử dụng enums. Cả hai const intenum s sẽ được đánh giá vào thời gian biên dịch, vì vậy bạn có cùng hiệu suất. Tuy nhiên, nó sạch hơn nhiều, sẽ dễ dàng hơn để gỡ lỗi (trình gỡ lỗi sẽ thực sự biết T là gì), nó an toàn kiểu và ít có khả năng phá vỡ các biểu thức phức tạp.

3

Do sự khác biệt giữa các khái niệm hằng số trong C và C++, trong C, về cơ bản, chúng tôi buộc phải sử dụng #define (hoặc enum) hầu hết thời gian. const không hoạt động trong C trong hầu hết các trường hợp. Tuy nhiên, trong C++ không có vấn đề như vậy, vì vậy nó thực sự là xấu thực hành dựa vào các hằng số #define d trong C++ (trừ khi bạn thực sự cần một hằng số thay thế bằng văn bản vì một lý do nào đó).

7

Không yêu cầu rằng T được lưu trữ "trong bộ nhớ" trong trường hợp thứ hai, trừ khi bạn làm điều gì đó như lấy địa chỉ của nó. Điều này đúng với tất cả các biến.

Lý do thứ hai tốt hơn là lần đầu tiên thường xuyên "biến mất" trong giai đoạn tiền xử lý để giai đoạn trình biên dịch không bao giờ nhìn thấy (và do đó không cung cấp cho bạn thông tin gỡ lỗi). Nhưng hành vi đó không được bắt buộc bởi tiêu chuẩn, thay vào đó là thực hành phổ biến.

Có rất ít nhu cầu sử dụng các câu lệnh #define khác hơn là để biên soạn có điều kiện. Các hằng số đơn có thể được thực hiện với const, nhiều hằng số liên quan có thể được thực hiện với enum và các macro có thể được thay thế bằng các hàm inline.

1

Macro tiền xử lý không tôn trọng phạm vi - đó là thay thế văn bản đơn giản - trong khi static const int blah = 1; có thể được đặt trong không gian tên. Trình biên dịch sẽ vẫn tối ưu hóa cả hai trường hợp (trừ khi bạn lấy địa chỉ của biến đó) nhưng nó là kiểu và phạm vi an toàn.

1

Có. Lý do lớn nhất là định nghĩa preprocessor không tuân theo các quy tắc Phạm vi của ngôn ngữ, gây ô nhiễm không gian tên toàn cầu, và tồi tệ hơn - chúng thậm chí thay thế trong những trường hợp như

x->sameNameAsPreprocessorToken 

Từ định nghĩa preprocessor được thay thế ở cấp văn bản , các thuộc tính bình thường khác của các biến không áp dụng - bạn có thể lấy địa chỉ của một const int, nhưng không phải của một hằng số # define'd.

Được ghi nhận bởi những người khác, bạn cũng thường mất khả năng gỡ lỗi và an toàn.

0

Một điểm thú vị khác là các hằng số tích phân toàn cầu có thể được tối ưu hóa bởi trình biên dịch để chúng không chiếm bất kỳ khoảng trống nào (ví dụ: bộ nhớ). Do đó, chúng có thể được coi là hằng số theo nghĩa đen khi chúng được sử dụng và tối ưu là hằng số dựa trên #define, mà không có tất cả các vấn đề về bộ xử lý trước.