Bạn bè sai? Keyword từ khóa tĩnh trong C so với C ++, C # và Java


8

Đối với tôi, việc sử dụng từ khóa statictrong C và các ngôn ngữ như C # và Java là "những người bạn giả" như "trở thành" trong tiếng Anh và "bekommen" trong tiếng Đức (= "to get" trong tiếng Anh), vì chúng có nghĩa là những thứ khác nhau.

Trong C staticcó nghĩa là, hàm hoặc biến chỉ có thể truy cập thông qua các hàm bên trong cùng một tệp nguồn, có thể so sánh với các privatehàm và thành viên trong C ++, Java và C #.

Trong C ++, Java và C # staticcó nghĩa là các phương thức không phải là thành viên của một thể hiện của lớp, nhưng thực tế là ít nhiều giống như các hàm C cộng với không gian tên.

IMHO hai khái niệm này khá khác nhau, vậy tại sao các nhà thiết kế của C ++ và Java và C # sau đó lại chọn statictừ khóa cho hành vi đó? Có một kết nối hợp lý mà tôi bỏ lỡ?

EDIT Tôi biết rằng, statictrong C không chi phối khả năng truy cập theo cách tương tự như privatetrong C ++, nhưng có thể được sử dụng theo cách đó, xem https://stackoverflow.com/a/1479639/124983

Câu trả lời:


9

Tôi có một cuốn sách về thiết kế C ++ của Bjarne Stroustrup (người phát minh ra C ++). Tôi không có nó ngay tại đây vì vậy tôi không thể tra cứu trích dẫn chính xác ngay bây giờ, nhưng trong đó anh ấy thừa nhận rằng khi anh ấy thêm staticvào C ++, anh ấy đã không hiểu đầy đủ ý nghĩa của nó trong C. Vì vậy, đó là lý do tại C ++ có ý nghĩa khác với trong C.

Java và C # được thừa hưởng ý nghĩa từ C ++.


Tạo một tài khoản ở đây chỉ để nâng cao câu trả lời này! Đây là thông tin tuyệt vời mà tôi sẽ không bao giờ muốn bỏ lỡ trong đời làm nhà phát triển phần mềm!
Maverick283

@ Maverick283 Đây là cuốn sách này: Thiết kế và tiến hóa của C ++
Jesper

14

Đáng chú ý, C ++ có cả hai cách sử dụng staticvà tôi nghĩ rằng có một phần ba ở đâu đó.

Nói chung, tôi nghĩ rằng việc sử dụng C statichoàn toàn không tương ứng với bất kỳ cách sử dụng từ tiếng Anh nào, trong khi tôi nghĩ rằng , ví dụ staticnhư một staticbiến thành viên, có ý nghĩa hơn nhiều.

Hãy nhớ rằng với tư cách là nhà thiết kế ngôn ngữ, bạn có động cơ hợp lý để giới thiệu ít từ khóa hơn vào ngôn ngữ, không cho phép ít mã hơn - đặc biệt là khi bạn đang cố tương thích nguồn với C, như trong C ++ và statictừ khóa đã tồn tại, vì vậy họ không thể phá vỡ bất kỳ chương trình C nào đang cố gắng biên dịch thành C ++ bằng cách sử dụng lại nó.

Chỉnh sửa: Tôi biết có một phần ba. C có staticcác biến cấp độ chức năng . Các staticthành viên chỉ là một phiên bản phạm vi của chức năng này. Do đó, cả hai cách sử dụng staticcó nguồn gốc từ C.


3
c có hai cách sử dụng tĩnh (liên kết và trọn đời), c ++ có cả hai và lớp một
jk.

1
@jk: Phiên bản lớp giống với cấp độ chức năng static, nó chỉ nằm trong một lớp thay vì một chức năng.
DeadMG

1
@jk. Nhiều người nghĩ rằng staticcó ba cách sử dụng trong C (biến phạm vi hàm, phạm vi đơn vị biên dịch cho các biến, phạm vi đơn vị biên dịch cho các hàm). Nó thực sự đang làm hai điều tương tự trong ba trường hợp này (liên kết và suốt đời), tôi chia sẻ ý kiến ​​của bạn về điều này. Quan điểm về ba cách sử dụng tĩnh trong C là phổ biến hơn, đáng buồn thay. Nó giúp mọi người hiểu làm thế nào để sử dụng nó, nhưng không phải làm thế nào nó thực sự hoạt động.
Gauthier

Bạn đang quên cách sử dụng tĩnh C99 mới: stackoverflow.com/questions 43230315/ trên
Austin

câu trả lời dưới đây là tốt nhất: softwareengineering.stackexchange.com/a/141880/253741 , nhưng để so sánh - 2 trong C: stackoverflow.com/a/728586/1200764 - C vs C ++: stackoverflow.com/a/29224988/1200764 - 3 trong C ++: cprogramming.com/tutorial/statickeyword.html
WillC

8

Trong C ++, staticbốn cách sử dụng sau:

  • Hàm toàn cầu (cấp độ tệp) và khai báo biến : với tĩnh, bạn đang chỉ định liên kết nội bộ . Điều đó có nghĩa là biểu tượng chỉ được sử dụng trong một đơn vị biên dịch đó (.cpp / cc / bất kỳ tệp nào, không phải là tiêu đề). Đây là những gì bạn đang đề cập đến như là "riêng tư".

  • Biến cục bộ : Thời lượng lưu trữ tĩnh xác định rằng biến sẽ giữ giá trị của nó giữa các lệnh gọi hàm.

  • Thành viên dữ liệu : Thành viên dữ liệu tĩnh được chia sẻ giữa các phiên bản của lớp (tức là chỉ có một bản sao của thành viên). Điều này gần giống với tĩnh C # và Java.

  • Hàm thành viên : Hàm thành viên tĩnh là các hàm thành viên không có thiscon trỏ ẩn ; chúng có thể được gọi mà không cần một ví dụ. Điều này cũng giống như trong C # hoặc Java.

Vì vậy, như bạn có thể thấy, họ đã bỏ đi hai trong số các ý nghĩa trên. Đối với phạm vi, khá dễ hiểu tại sao: cả C # và Java (và thậm chí C ++) đều dựa vào các không gian tên để làm điều đó. C ++ có thể có tính năng liên kết nội bộ để tương thích ngược. Việc bỏ các biến cục bộ tĩnh có lẽ là hai lần: lần đầu tiên, có thể khó hiểu đầy đủ hậu quả của nó và các ngôn ngữ này nhắm đến sự đơn giản. Thứ hai, cả Java và C # đều có trình thu gom rác (mà tôi có thể tưởng tượng) gây khó khăn khi thực hiện hành vi đó.


"C ++ có thể có tính năng liên kết nội bộ để tương thích ngược." - người ta có thể thêm (IIRC) rằng Tiêu chuẩn C ++ trước tiên không chấp nhận việc sử dụng này static(ưu tiên các không gian tên ẩn danh) và sau đó, trong phiên bản hiện tại của nó, C ++ 11 đã không còn sử dụng staticcho việc này. (tất cả IIRC)
Martin Ba

Có thật không? Tôi khá chắc chắn rằng trình biên dịch đã không tôn trọng sự phản đối này sau đó, bởi vì nó đã hoạt động với ít nhất hai trình biên dịch chính (gcc và MSVC).
Tamás Szelei

Không có trình biên dịch đã ném nó ra xa như tôi biết. Tuy nhiên, tôi nghĩ rằng tiêu chuẩn '98 / '03 đã phản đối nó hoặc somesuch. Điều tôi thực sự muốn nói với nhận xét của mình là điều liên kết nội bộ là một tính năng rõ ràng cũng được coi là hữu ích trong C ++, vì vậy nó không chỉ có khả năng tương thích ngược.
Martin Ba

Cách làm "c ++ - y" tương tự là khai báo trong một không gian tên ẩn danh.
Tamás Szelei

"Là khai báo trong một không gian tên ẩn danh" - ngoại trừ việc nó không giống với kỹ thuật. (Tôi xin lỗi vì không có nhiều tài liệu tham khảo, nhưng tôi thiếu thời gian để tìm kiếm nó. của WG21 ...)
Martin Ba

3

C ++ đã lấy nó từ C, vì C ++ thích sử dụng lại các từ khóa hiện có thay vì giới thiệu những từ khóa mới, để giảm thiểu việc phá vỡ mã hiện có.

Java và C # sau đó lấy nó từ C ++.


3

C statickhông chi phối khả năng tiếp cận và không gây khó chịu privatetheo cách bạn đề xuất.

Ở phạm vi tệp, nó chi phối tính khả dụng của tên (ký hiệu liên kết), chứ không phải điều - bạn có thể chuyển một con trỏ tới một statichàm hoặc toàn cục từ đơn vị dịch thuật nơi nó được xác định thành mã trong một tệp khác và nó sẽ hoạt động tốt.

Cách C ++ để làm điều này (như DeadMG nói, cách C vẫn có sẵn) là sử dụng một không gian tên ẩn danh.

Trong phạm vi chức năng, về cơ bản, nó thay thế biến cục bộ bằng một biến toàn cục chỉ có thể truy cập (theo tên một lần nữa!) Bên trong hàm đó - điều này giống hệt trong C ++ (vì vậy, không có cách nào để thực hiện C ++ hơn) .

Về lý do tại sao C ++ sử dụng staticvòng loại cho các thành viên của lớp; Có lẽ đúng khi nói rằng điều này là để giảm thiểu số lượng từ khóa mới được giới thiệu. (Lưu ý việc sử dụng lại tự động gần đây để so sánh).

Gọi dữ liệu theo từng lớp tĩnh (vì vậy, dữ liệu theo từng trường hợp là động ) có vẻ khá trực quan đối với tôi, nhưng vì tôi không nhớ quá trình hình thành trực giác đó, tôi thực sự không thể nhận xét khách quan về việc liệu nó có ý nghĩa khi bắt đầu không ngoài.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.