2009-03-24 33 views
8

Nhà phát triển trong nhóm Tôi giám sát muốn khai báo biến là hằng số trong các thử nghiệm của mình, ví dụ: const int someValue = 1; (thay vì chỉ int someValue = 1;).Ý kiến ​​của bạn về việc khai báo hằng số bên trong các phương thức ...?

Khi tôi thấy điều này, tôi thấy nó hơi lạ và đặt câu hỏi về những gì anh đã làm. Lập luận của anh ta là điều này là hợp lý cho các mục đích của bài kiểm tra này - bởi vì giá trị anh ta gán không bao giờ thay đổi.

Tôi đã luôn nghĩ về các hằng số như một thứ cần được khai báo ở cấp độ lớp. Tuy nhiên tôi thấy quan điểm của nhà phát triển này.

Ý kiến ​​của bạn là gì? Và, xét nghiệm sang một bên, bạn sẽ khai báo hằng số trong các phương pháp bình thường? Nếu đúng thì tại sao?

Trả lời

3

Ý tưởng là bạn chỉ để lại nội dung có thể thay đổi nếu có lý do cụ thể cho nó — điều này giúp bạn dễ dàng hơn trong việc giải thích mã của mình theo cách đó.

3

Tất nhiên giá trị cần được đặt tên, nhưng điều đó không cần phải thay đổi, nên được gọi là hằng số, vì đó là giá trị của nó.

Chắc chắn, đôi khi một hằng số có thể là một phần của giao diện và/hoặc cần được sử dụng trong phạm vi rộng hơn, và sau đó nó phải được khai báo ở một nơi thích hợp. Nhưng nếu nó thực sự là địa phương, sau đó tôi thấy không có gì lạ về việc làm cho nó như vậy.

9

Nếu số nhận dạng chỉ được sử dụng trong chức năng được khai báo, tại sao lại là phạm vi rộng hơn với nó. Nếu giá trị được gán cho định danh không nên thay đổi thì đánh dấu nó là như vậy rất hữu ích cho trình biên dịch cũng như phát hiện lỗi.

20

Nói chung, tôi nghĩ rằng nó luôn luôn là một ý tưởng tốt để làm cho ý định của bạn dọn đường này, đối với một số lý do:

  • Nó dễ dàng hơn để hiểu những gì bạn có nghĩa là khi bạn đã viết nó.
  • Dễ dàng hơn cho những người khác biết về mã của bạn khi họ đọc mã.
  • Trình biên dịch dễ dàng đưa ra suy luận về những gì bạn muốn làm.
  • Trình biên dịch để ngăn chặn các lỗi logic dễ dàng hơn.

Biến hằng số là cách hoàn toàn hợp pháp để thực hiện tất cả các điều trên, trong trường hợp cụ thể có ý định "Tôi không muốn biến này thay đổi giá trị của nó".

3

Nếu giá trị được phạm vi theo phương pháp (tức là không được sử dụng bên ngoài, nhưng được sử dụng một vài lần bên trong), thì nó có ý nghĩa tốt. Đặc biệt, nếu làm việc với xml, bạn có thể có một cái gì đó giống như một không gian tên xml được sử dụng (chỉ trong một phương thức) nhiều lần, nhưng nó chắc chắn không phải cái gì bạn muốn duy trì nhiều hơn một lần - const là lý tưởng.

Xét về C#, điều này cũng có tác động đối với việc đóng cửa:

const int i = 27; 
Func<Foo,bool> predicate = foo => foo.Bar == i; 

là khác nhau để:

int i = 27; 
Func<Foo,bool> predicate = foo => foo.Bar == i; 

Thứ hai phải tạo ra một lớp capture, vv - là người đầu tiên chỉ là một tĩnh phương thức (không có trạng thái) và hiệu quả hơn (không có đối tượng heap cho mỗi lần sử dụng, không có tham chiếu, vv).

+0

Trình biên dịch có đủ thông minh để phát hiện điều này không? – erikkallen

+0

@erikkallen: Vâng, tất nhiên rồi. Đó là lý do tại sao hai người lại khác nhau. Nếu trình biên dịch không thể phát hiện nó, thì chúng sẽ không thể được xử lý khác nhau. –

+0

@Tomalak: Có, nhưng trình biên dịch cũng có thể đủ thông minh để biết rằng giá trị không bao giờ được sửa đổi sau khi đóng được tạo. – erikkallen

5

Nếu bạn định sử dụng ngôn ngữ được nhập tĩnh, thì tại sao không chỉ đi toàn bộ chín thước? Sử dụng const để cho biết rằng bạn không muốn giá trị thay đổi sau lần chuyển nhượng đầu tiên. Hãy để trình biên dịch lỗi bạn nếu bạn goof.

Tôi khá thích từ khóa const trong C thông số phương pháp ++ vì lý do chính xác này ...

1

Tuyên bố một hằng số biến sẽ ngăn cản bạn vô tình thay đổi giá trị của nó. Điều này cũng có thể dẫn đến tối ưu hóa trình biên dịch.

0

Tôi chưa bao giờ thấy điều này trước đây nhưng điều đó có ý nghĩa. Tôi sẽ để cho lập trình viên tiếp tục theo cách mà anh ấy đã và đang phát triển.

1

Tôi có xu hướng khai báo bất kỳ giá trị nào không thay đổi const/final và khuyến khích những người khác làm việc theo nhóm. Thông thường trong Java, trong đó cuối cùng có nghĩa là 'được gán một lần và một lần duy nhất' thay vì const của C 'khởi tạo và không thay đổi', bạn có thể tạo ra các phương thức mà các giá trị không thay đổi duy nhất là vòng lặp lặp.

1

Do nó ở khắp mọi nơi mà nó có thể:

  • nó làm cho mã dễ đọc;
  • nó yêu cầu trình biên dịch để kiểm tra lỗi dịp bạn:

    void some_class1::doSomething(const some_class2& cs2) 
    { 
        // code 
        cs2 = cs2; // !!! misspelling cs2 instead cs2_ 
        // 
    } 
    
  • nó giúp bạn với khả năng tương thích với const đang -correct;

  • giúp với đóng gói.
10

Từ Effective C++ Scott Meyers (chương 3):

Sử dụng const bất cứ khi nào có thể.

Điều tuyệt vời về const là nó cho phép bạn chỉ định một hạn chế ngữ nghĩa - một đối tượng cụ thể nên không được sửa đổi - và trình biên dịch sẽ thực thi hạn chế đó. Nó cho phép bạn giao tiếp với cả hai trình biên dịch và các lập trình viên khác mà một giá trị nên vẫn bất biến. Bất cứ khi nào điều đó là đúng, bạn nên chắc chắn để nói như vậy, bởi vì theo cách đó bạn tranh thủ sự trợ giúp của trình biên dịch của bạn trong việc đảm bảo ràng buộc không bị vi phạm.

0

Để kiểm tra, điều này rõ ràng là tuyệt vời. Đối với mã 'thông thường', bạn có thể xem mã theo cả hai cách. Trên một đầu, phạm vi của bất cứ điều gì trong mã nên càng nhỏ càng tốt.Ở đầu bên kia, bạn có thể nói rằng hằng số có nhiều khả năng được sử dụng troughout một lớp và nên được khai báo ở cấp lớp mọi lúc, để ngăn chặn các hằng số kép.

Tôi sẽ nói, chỉ khai báo hằng số cấp lớp và chỉ sử dụng hằng số phương thức khi có lý do chính đáng cho nó. Một lý do có thể là mục đích của phương pháp là cung cấp trừu tượng về một số cuộc gọi API và bạn yêu cầu một số giá trị không đổi cho điều này. Trong trường hợp này, bạn không muốn các hằng số cấp lớp làm lộn xộn phần còn lại của một lớp.

2

Lợi thế của việc khai báo nó là bạn không thể "vô tình" sửa đổi nó theo cách tối nghĩa để kiểm tra mã có thể bị mất. Ví dụ bằng cách chuyển nó bằng tham chiếu vào một hàm làm thay đổi tham số của nó.

Những bất lợi có thể tranh cãi là bạn không thể (dễ dàng) chuyển nó vào mã mà không tham chiếu không const mà nó không thực sự sửa đổi. Nếu bạn thực sự tin vào C++, đây thực sự là một lợi thế trong ngụy trang, bởi vì nó khuyến khích bạn làm cho phần còn lại của mã của bạn const-correct. Nhưng nếu bạn phải thực hiện các thay đổi nhanh chóng (ví dụ: khi gỡ lỗi) hoặc nếu bạn đã xuất bản API và không thể thay đổi nó, thì có vẻ như bạn thích một ngụy trang tốt.

Nếu chức năng ngắn, thì bạn không thực sự cần "const" để cho bạn biết liệu biến địa phương có được sửa đổi rõ ràng bằng cách gán hay không. Bạn có thể thấy tất cả các công dụng của biến ngay tại đó, trước mặt bạn. Nhưng trong cuộc sống thực, đôi khi các chức năng nhận được lâu; và nơi mọi người sử dụng tham số tham chiếu không const và đôi khi thậm chí là macro; và nơi bạn muốn đọc và hiểu mã càng nhanh càng tốt; sau đó nó có thể giúp một chút.

Tôi có xu hướng sử dụng nó khi tôi nhớ và không đổ mồ hôi nếu tôi quên. Tôi nhận được hầu hết sử dụng ra khỏi nó khi tôi cần phải loại bỏ const từ một biến. Điều đó nói với tôi rằng quan niệm ban đầu của tôi về biến đó là sai, và tôi cần phải kiểm tra cẩn thận rằng không có biểu thức nào sử dụng nó thực sự dựa vào nó không thay đổi. Cho rằng C + + có từ khóa const, nếu bạn đang đi để viết mã dựa trên một biến không thay đổi, bạn cũng có thể nhận được trình biên dịch về phía bạn.

Thường không đáng lo ngại về tối ưu hóa trình biên dịch. Một trình biên dịch tốt (gcc) có thể nói rằng nếu bạn không sửa đổi một biến, và không tham chiếu đến nó, thì nó có thể áp dụng các tối ưu thích hợp cho dù bạn đánh dấu nó hay không.

3

Rất nhiều nhà phát triển C++ dày dạn thực sự tin rằng "const" phải là mặc định và bạn sẽ phải tuyên bố rõ ràng điều gì đó không phải là const. Tất nhiên, sử dụng const bất cứ khi nào nó có ý nghĩa để làm như vậy. Nếu một cái gì đó không nên thay đổi bên trong một hàm, hãy làm cho nó const. Nó không chi phí bất cứ điều gì, và nó giúp tuyên bố ý định.

Các vấn đề liên quan