Tại sao tôi học C ++ 11, khi biết C và C ++? [đóng cửa]


28

Tôi là một lập trình viên trong C và C ++, mặc dù tôi không dính vào một trong hai ngôn ngữ và viết hỗn hợp cả hai. Đôi khi có mã trong các lớp, có thể với quá tải toán tử, hoặc các mẫu và STL tuyệt vời rõ ràng là một cách tốt hơn. Đôi khi việc sử dụng một con trỏ hàm C đơn giản dễ đọc và rõ ràng hơn nhiều. Vì vậy, tôi tìm thấy vẻ đẹp và tính thực tế trong cả hai ngôn ngữ. Tôi không muốn tham gia vào cuộc thảo luận về "Nếu bạn trộn chúng và biên dịch với trình biên dịch C ++, thì đó không phải là một bản phối nữa, tất cả đều là C ++" Tôi nghĩ tất cả chúng ta đều hiểu ý tôi khi trộn chúng. Ngoài ra, tôi không muốn nói về C vs C ++, câu hỏi này là tất cả về C ++ 11.

C ++ 11 giới thiệu những gì tôi nghĩ là những thay đổi đáng kể đối với cách hoạt động của C ++, nhưng nó đã đưa ra nhiều trường hợp đặc biệt, ngoại lệ và bất thường thay đổi cách các tính năng khác nhau hoạt động trong các trường hợp khác nhau, đặt các hạn chế đối với nhiều kế thừa, định danh đóng vai trò là từ khóa, tiện ích mở rộng của chuỗi ký tự, bắt hàm biến lambda, v.v.

Tôi biết rằng tại một thời điểm nào đó trong tương lai, khi bạn nói C ++, mọi người sẽ giả sử C ++ 11. Giống như khi bạn nói C ngày nay, rất có thể bạn có nghĩa là C99. Điều đó khiến tôi cân nhắc việc học C ++ 11. Rốt cuộc, nếu tôi muốn tiếp tục viết mã bằng C ++, đôi khi tôi có thể cần phải bắt đầu sử dụng các tính năng đó đơn giản chỉ vì các đồng nghiệp của tôi có.

Lấy C làm ví dụ. Sau nhiều năm, vẫn còn nhiều người học và viết mã bằng C. Tại sao? Bởi vì ngôn ngữ là tốt. Điều tốt có nghĩa là, nó tuân theo nhiều quy tắc để tạo ra một ngôn ngữ lập trình tốt. Vì vậy, ngoài việc mạnh mẽ (dễ hay khó, hầu như tất cả các ngôn ngữ lập trình đều có), C là thường xuyên và có một vài ngoại lệ, nếu có. C ++ 11 tuy nhiên, tôi không nghĩ vậy. Tôi không chắc chắn rằng những thay đổi được giới thiệu trong C ++ 11 đang giúp ngôn ngữ trở nên tốt hơn.

Vì vậy, câu hỏi là: Tại sao tôi học C ++ 11?

learning  c++  c  c++11 

3
Tôi hiểu rằng không nên có một cơn thịnh nộ của C ++ 11 trong diễn đàn này và tôi hoàn toàn đồng ý về điều này: mọi nhà phát triển đều có quyền có sở thích cá nhân về ngôn ngữ và công cụ lập trình. Tuy nhiên, có một vấn đề thực tế hơn đối với tôi: Tôi là nhà phát triển C ++ và tôi không thích C ++ 11, tôi sẽ buộc phải sử dụng C ++ 11 hoặc rời khỏi thị trường / chuyển sang ngôn ngữ khác trong một vài năm?
Giorgio

Vâng, tôi đã nghĩ một chút về điều đó, tất nhiên có những ngôn ngữ hiện đại hơn từ đầu như ngôn ngữ lập trình D hoặc Go. Chúng có thể phù hợp với miền vấn đề của bạn, dễ dàng hơn, v.v. Tuy nhiên, thị phần .. không ai trong số những người chơi quan trọng trong ngành hỗ trợ D và thậm chí Go dường như là một trong những "thí nghiệm" của googles .. Vì vậy, động lực đằng sau C + +11 phải là những cải tiến hữu ích cho phép bạn viết mã dễ đọc hơn, an toàn hơn và nhanh hơn cũng như hỗ trợ công nghiệp rộng rãi.
Nils

@giorgio, trong hai năm qua, tôi đã ngừng sử dụng C ++ nhiều như trước đây (chủ yếu là vì nhận ra người hâm mộ C ++ tôn giáo như thế nào, đọc câu trả lời cho câu hỏi này), nhưng tôi vẫn sẵn sàng làm việc trong thư viện C ++ mà tôi sẵn sàng làm việc trong thư viện C ++. đã sử dụng C ++ 11 cho. Kinh nghiệm của tôi là thế này: C ++ 11 giải quyết rất nhiều góc khuất của C ++, và điều đó thật đáng ngưỡng mộ và thực sự nó cải thiện nó. Cách nó làm nó có các góc khốn nạn của riêng nó (xem bài đăng chưa được chỉnh sửa ban đầu). Tuy nhiên, những góc khuất đó dường như không còn tồn tại nếu bạn làm những việc "theo cách thông thường" (ví dụ: không lưu trữ lambda để sử dụng trong tương lai).

@giorgio, ý tôi là, C ++ 11 có thể trông tệ ngay từ đầu, thực tế bản thân C ++ trông rất tệ, nhưng nếu bạn ổn với C ++, có lẽ bạn cũng sẽ thích C ++ 11. Chỉ cần tránh chạm vào những phần nhảm nhí của nó và bạn thực sự có thể thích nó.

@anon: Một cách để loại bỏ những phần nhảm nhí của ngôn ngữ là cắt bỏ quá khứ và bắt đầu một ngôn ngữ mới, giống như Apple đang làm với Swift (chỉ nêu một trong số rất nhiều ví dụ). Giao diện với mã kế thừa có thể được thực hiện thông qua việc biên dịch riêng biệt. Vấn đề với C ++ là nó được mở rộng vô thời hạn, có lẽ bởi vì nó được hỗ trợ bởi một cộng đồng người hâm mộ tin rằng tôn giáo C ++ là ngôn ngữ thực sự. Điểm mấu chốt: Tôi thấy C ++ 03 hơi nhảm nhí nhưng nó đã hoàn thành công việc, đặc biệt là nhờ các thư viện như Qt và boost. Mặt khác, tôi sẽ giữ tay C ++ 11.
Giorgio

Câu trả lời:


24

Bạn nên học nó nếu bạn nghĩ rằng bạn sẽ cần phải biết nó trong tương lai để có được một công việc. Nếu bạn tự tin bạn sẽ vẫn có thể tiếp thị trong lực lượng lao động dưới dạng C / C ++ [và bất cứ điều gì khác mà bạn có thể biết] thì đừng học nó. Nếu sếp của bạn bảo bạn sử dụng C ++ 11, hãy nói "không, tôi không làm điều đó". Nếu anh ta sa thải bạn, hãy đi làm việc ở nơi khác. Tìm hiểu C ++ 11 khi bạn thấy trước rằng bạn sẽ không thể tìm được việc làm thỏa đáng với các kỹ năng bạn biết hiện tại.

Muốn làm rõ lý do của tôi: Tôi không chống C ++ 11. Chỉ cần nói rằng bạn có thể khái quát câu hỏi của OP thành "Tại sao tôi nên học X". Tôi chưa bao giờ học ML, lược đồ hoặc haskell vì tôi có công việc với C và C ++. Tôi chắc rằng những ngôn ngữ đó hữu ích cho ai đó, nhưng chúng không có ích cho tôi để học ngay bây giờ. Nếu ai đó cho tôi tiền tốt để lập trình trong ML, tôi có thể cố gắng học nó.


3
Nếu bạn là nhà phát triển "C / C ++" và nếu sếp của bạn bảo bạn sử dụng C ++ 11, bạn có nên tiếp tục và thêm nó vào kho vũ khí của mình không? Tôi đồng ý rằng bạn không nên dành toàn bộ thời gian để học ngôn ngữ chỉ vì mục đích học chúng, nhưng khi sếp của bạn nói: "Học cái này", có lẽ bạn nên tiếp tục và học nó. Nó cũng làm cho bạn có nhiều thị trường hơn, trái ngược với việc phải giải thích về ứng dụng tiếp theo của bạn rằng bạn đã bị sa thải vì không tuân theo.
Panzercrisis

Haskell ... Hài hước, vì sự bao gồm từ từ của lambdas trong C ++. : P
rbaleksandar

85

Thật đơn giản. C ++ 11 làm cho mã dễ dàng hơn, dễ viết hơn và nhanh hơn.

nullptrlà một cải tiến VAST so với cái cũ 0. Đó là loại an toàn và không chuyển đổi khi không nên - không giống như 0. Đó là một điều tốtnullptrsẽ không chuyển đổi thành một int. Nó hoàn toàn không có ý nghĩa cho điều đó xảy ra. Bạn có biết Ủy ban C ++ tìm thấy gì khi họ cố gắng xem xét #define NULL nullptr? Thứ như char c = NULL;. Làm thế nào là khủng khiếp? Lý do duy nhất có một ngoại lệ ở đây là vì boolđược coi là một loại tách rời, điều này khá sai - nhưng trước đó đã có trong C ++ và ở C. Thực tế là nullptrkhông chuyển đổi là tốt , thật tuyệt và bạn nên yêu thích nó.

Hoặc làm thế nào về các tài liệu tham khảo rvalue và các mẫu matrixdic? Nhanh hơn, mã chung hơn. Đó là một chiến thắng hoàn toàn ngay tại đó.

Làm thế nào về những cải tiến thư viện? Những thứ như function, unique_ptrshared_ptrtốt hơn nhiều so với những gì trước đây, không thể tranh luận rằng cách C ++ 03 tốt hơn.

#define adding_func(x, y) ((x)+(y))

Thậm chí không tương đương từ xa. Macro là xấu vì sáu tỷ lý do. Tôi sẽ không trích dẫn tất cả chúng ở đây, nhưng ai cũng biết rằng nên tránh các macro cho hầu hết các mục đích mà chúng có thể tránh được. Bạn sẽ làm gì khi nó

#define add_twice(x) (x + x)

Oh chờ đợi, tôi hy vọng bạn đã không tăng hoặc một cái gì đó trên x. Mà phiên bản chức năng mẫu là hoàn toàn miễn dịch. Tôi cũng hy vọng rằng bạn không đánh giá cao không gian tên , ví dụ.

Sau đó, bạn mở ra một thế giới của hành vi không xác định để sử dụng các biến bên ngoài có phạm vi đã hoàn thành.

Trong một API chức năng, ví dụ thuật toán STL, thì tham chiếu là tốt. Nếu đó là một cuộc gọi lại được lưu trữ, thì bạn cần phải nắm bắt theo giá trị. Bất cứ tài liệu nào bạn có về chức năng nên chỉ rõ những gì cần thiết. Thực tế là mã được viết bằng lambda không liên quan đến vấn đề đề cập đến các biến cục bộ - nếu bạn vượt qua một đối tượng hàm thông thường, thì bạn sẽ gặp rắc rối chính xác. Và nó không phải là một vấn đề. Ở tất cả. Bởi vì nó vốn đã rõ ràng khi bạn có thể và không thể tham khảo các biến cục bộ.

Lấy C làm ví dụ. Sau nhiều năm, vẫn còn nhiều người học và viết mã bằng C. Tại sao?

Có nhiều người không đánh răng vào buổi sáng. Có rất nhiều kẻ giết người, và những kẻ hiếp dâm, và gái mại dâm. Và các chính trị gia. Những người tự tử. Bạn sẽ tranh luận rằng do đó làm cho các hoạt động này tốt hay hữu ích? Tất nhiên là không. Đó là một lời ngụy biện logic mà chỉ vì ai đó đã làm nó, do đó nó phải tốt hoặc hữu ích.

C vẫn đang được viết vì ba lý do: bởi vì C ++ là một con chó cái để thực hiện, ví dụ như trên chế độ nhúng hoặc kernel; bởi vì các cơ sở mã kế thừa được viết bằng C và sẽ tốn quá nhiều chi phí để nâng cấp, mặc dù điều đó có thể nghi ngờ khi có sự can thiệp C tuyệt vời của C ++; và bởi vì những người viết nó không biết cách lập trình. Đó là nó. Không có lý do nào khác để viết C.

Nếu bạn lấy C hoặc kiểu C ++ cũ, bạn sẽ không tìm thấy nhiều ngoại lệ.

Làm thế nào về các mảng kiểu C thảm hại, cho một ví dụ đơn giản? Số người không thể nhận được mảng và con trỏ thẳng trong đầu họ là rất tục tĩu. Chưa kể đến việc thư viện C Standard cực kỳ không an toàn.

Lập luận cốt lõi của bạn đầy những ngụy biện logic và hiểu lầm.


7
> Thực tế là nullptr không chuyển đổi là tốt, thật tuyệt và bạn nên yêu thích nó. OK ý kiến ​​của bạn, nhưng hãy bình tĩnh một chút về những gì người khác nên YÊU, xin vui lòng ... Bước tiếp theo là luật sư C ++!
Emilio Garavaglia

5
Tôi nghĩ phần sau của câu trả lời của bạn là lý do tại sao C ++ nên được ưu tiên hơn C. Đó là điều không thể. "Thư viện C không an toàn" - làm thế nào trên trái đất này trả lời câu hỏi? Ý tôi là tất nhiên người ta nên tìm hiểu các tính năng mới mà C ++ 11 cung cấp, nhưng C và C ++ KHÔNG có nghĩa là làm những việc tương tự. Nếu C ++ là một con chó cái để thực hiện ở mức thấp, thì C #, Java, Python và không có gì chúng không có ý định chạy ở mức thấp đó. Chỉ vì C ++ biên dịch thành mã gốc không có nghĩa là bạn có thể sử dụng OO và việc đập trang được liên kết với nó cho mã cấp hạt nhân quan trọng.
yati sagade

11
@Shahbaz, rõ ràng bạn phải tìm hiểu thêm một chút về ngôn ngữ lập trình (ví dụ: hệ thống loại, phạm vi từ vựng, v.v.), tất cả các nhận xét của bạn hoàn toàn không đồng bộ. Bắt đầu với cuốn sách này: amazon.com/Theories-Programming-Lacular-John-Reynolds/dp/ mẹo
SK-logic

5
@yati: C ++ có cùng hệ thống mô-đun với C. Các hàm thành viên được triển khai như các hàm C cũ đơn giản. Các hàm ảo được triển khai giống như tải các hàm từ DLL. Không có gì trang đập về những điều đó. Và vâng, điều đó chắc chắn nhất được áp dụng. Để bắt đầu, niềm tin của bạn rằng Unix là tốt nhất là chủ quan. Đó là 5% thị phần cho thấy khác. Và thứ hai, ngay cả khi tôi yêu thích Unix không có hồi kết, một ví dụ sẽ không tạo ra xu hướng. Điều tương tự cũng đúng với các ví dụ khác mà bạn trích dẫn. Ví dụ nào? Chúng vô nghĩa. C ++ chỉ phù hợp với các thủ tục như C là.
DeadMG

8
@yatisagade C ++ là ngôn ngữ đa mô hình không thực thi các chức năng ảo cho mọi thứ và các chương trình của tôi trong C ++ cũng tương tự. Các bộ phận của nó sử dụng thiết kế hướng đối tượng, các bộ phận của nó là chức năng, v.v., tùy thuộc vào cách giải quyết vấn đề phụ cụ thể đó tốt nhất. Tôi đánh giá cao C ++ vì đã thêm phong cách hướng đối tượng và tôi đánh giá cao C ++ 11 vì đã mở rộng hỗ trợ rất nhiều cho lập trình chức năng.
David Stone

29

C ++ 11 không phải là một ngôn ngữ mới; nó chỉ là một phần mở rộng / sửa đổi của C ++ mà bạn đã biết. C ++ 11 giống như bất kỳ ngôn ngữ lập trình nào khác bao gồm các tính năng. Rất nhiều trong số họ đã ở đó từ trước, một số trong số họ là mới. Nhưng câu hỏi của bạn thực sự là, tôi có nên tìm hiểu tất cả các tính năng của ngôn ngữ (trong trường hợp này là C ++ 11) hay chỉ làm quen với 90% của nó?

IMO ngay cả khi bạn không sử dụng tất cả ngôn ngữ, ít nhất bạn cũng nên đọc những tính năng mới làm cho bạn. Rất nhiều trong số chúng được giới thiệu để làm cho mã thư viện / khung (đặc biệt là các mẫu) dễ viết hơn (ví dụ, trước khi chuyển tiếp hoàn hảo C ++ 11 là không thể), nhưng nếu bạn chưa bao giờ có nhu cầu về tính năng đó trước đó, thì rất có thể bạn đã thắng Tôi nhận thấy rằng các tính năng này đã được thêm vào trong C ++ 11.

Mặt khác, nếu trước đây bạn đã từng viết mã thư viện / mã lõi bắt chước một số chức năng STL / Boost và thấy mình bị giới hạn bởi ngôn ngữ vì bạn đã đạt 95% để có một giải pháp thanh lịch, tuyệt vời nhưng sau đó bạn đã dừng lại vì bạn phát hiện ra ngôn ngữ đơn giản là không hỗ trợ những gì bạn muốn, bạn sẽ nhận ra sức mạnh thực sự tuyệt vời của C ++ 11. Kể từ khi nhóm của chúng tôi nâng cấp lên VS2010 (và chúng tôi đã phát hiện ra Boost trong quá trình), tôi đã có thể tạo ra một số mã tuyệt vời điên rồ, điều đó đơn giản là không thể trước những thứ như tham chiếu giá trị r và chuyển tiếp tham số mẫu.

Ngoài ra, những thứ như lambda có thể trông xa lạ, nhưng chúng không giới thiệu một cấu trúc mới. Thay vào đó họ làm cho những gì chúng ta từng có trước đây trở nên dễ dàng hơn để viết. Trước đây, mỗi hàm lambda sẽ phải là một lớp riêng biệt. Bây giờ chỉ là {... mã ...}. Yêu nó.

Điều quan trọng là đừng nhìn vào các tính năng này và nghĩ xem danh sách này đáng sợ đến mức nào. Thay vào đó, hãy sử dụng C ++ như bạn vẫn thường làm và khi bạn gặp một số tình huống trong đó các tính năng C ++ 11 mới này có ích (hơn 90% mọi người sẽ không bao giờ đạt đến điểm đó), bạn sẽ rất vui khi tiện ích mở rộng để ngôn ngữ đã được thực hiện. Hiện tại, tôi khuyên bạn chỉ nên học đủ về ngôn ngữ để biết những gì ở đó, không nhất thiết phải sử dụng tất cả ngôn ngữ đó như thế nào.


7
@Shahbaz - Tôi nghĩ bạn vẫn còn thiếu ý định tại sao các chức năng không tên được thêm vào. Và "sử dụng các biến mà không lấy chúng làm đầu vào" được gọi là đóng và có sẵn trong nhiều ngôn ngữ cấp cao khác. Nếu bạn đã viết rất nhiều mã mẫu với các đối tượng functor, với C ++ 11, bạn sẽ được chào đón các hàm lambda với vòng tay rộng mở. Hãy nghĩ về nó theo cách này ... khi trình biên dịch tạo mã máy, không có chức năng nào như hàm mẫu hoặc lớp. Tất cả chúng đều được "khởi tạo" để tạo các lớp / hàm cụ thể trước thời điểm đó. Lambdas là điều tương tự khi nói đến trạng thái ...
DXM

5
... Chức năng. Thay vì yêu cầu mọi người viết một tấn mã, một mã cho mỗi loại functor và mọi phần tử đóng mà bạn muốn truyền vào, C ++ 11 cho phép bạn chỉ định một cú pháp phím tắt và nó sẽ tự động khởi tạo toàn bộ lớp functor bên trong giống như nó khởi tạo các mẫu. Một lần nữa, hãy nhớ rằng hầu hết các tính năng này sẽ không được sử dụng trong 98% mã cấp độ ứng dụng, nhưng chúng đã được thêm vào để làm cho các thư viện như STL / Boost mạnh mẽ hơn và dễ dàng hơn để thực hiện / duy trì / gỡ lỗi
DXM

10
@Shahbaz: Được rồi, bạn không hiểu chức năng lambda hoặc đóng cửa. Sự hợp lý của nó. Thực tế là chúng được sử dụng trong nhiều ngôn ngữ khác nhau sẽ gợi ý rằng chúng hữu ích, cho dù bạn có hiểu chúng hay không và bạn nên hiểu chúng trước khi chỉ trích chúng quá nhiều.
David Thornley

8
@Shahbaz: Nếu bạn nghĩ rằng các bao đóng tương tự như các biến toàn cục, bạn không hiểu các bao đóng. (Gợi ý: các biến toàn cục gây ra vấn đề vì bất kỳ hàm nào cũng có thể sửa đổi chúng.) Nếu bạn hiểu khái niệm lambdas, không phải việc triển khai, bạn sẽ không quy kết nó là nhầm lẫn giữa các lớp so với mã. Mọi thứ trong Tiêu chuẩn C ++ đều có vì những lý do có sức thuyết phục đối với một số lượng lớn người thông minh. Bạn không cần phải đồng ý với lý do, nhưng không biết họ đang chỉ trích vì sự thiếu hiểu biết.
David Thornley

6
@Shahbaz, hoàn toàn không có sự tương đồng giữa các lần đóng cửa và toàn cầu, bạn hoàn toàn thiếu điểm. Đọc này: en.wikipedia.org/wiki/Lambda_calculus và làm nổ tung bộ não của bạn: en.wikipedia.org/wiki/Combinatory_logic
SK-logic

18

Có quá khó để viết một hàm, đến mức bạn phải viết nội dung của hàm nội tuyến với mã, bên cạnh việc không có tên?

Khi bạn làm điều đó, bạn cuộn lên hoặc mở một tệp nguồn mới và thêm định nghĩa của hàm ở đó. Sau đó, bạn phải quay lại và tiếp tục những gì bạn đang làm việc, điều đó làm bạn mất tập trung ở một mức độ nào đó.

Ngoài ra, khi những người khác đang đọc mã của bạn, lambda có thể tự ghi lại nhiều tài liệu hơn trong một số trường hợp, thay vì nói "Ồ, chức năng này làm gì?" và nhảy đến tuyên bố của nó, bạn có thể nhìn vào những gì nó đang làm ở vị trí của nó.

Có một bài nói hay của Herb Sutter về lambdas, có lẽ anh ta có thể thuyết phục bạn tốt hơn:

http://channel9.msdn.com/events/PDC/PDC10/FT13

Chà, tại sao bạn không viết mã ở đó thay vì biến nó thành hàm lambda?

Bởi vì bạn không thể làm điều đó khi bạn đang sử dụng thuật toán STL hoặc bất kỳ chức năng nào bạn đang sử dụng đòi hỏi bạn phải vượt qua một chức năng.

#define thêm_func (x, y) ((x) + (y))

Không có cách nào để biện minh cho việc sử dụng này thay vì lambdas, bạn không thể điền mã của mình bằng macro ở mọi nơi. Macro và chức năng có các mục đích khác nhau và nói chung, một mục đích không phải là sự thay thế cho mục đích khác.

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

Tôi đồng ý, điều này là xấu xí. Tuy nhiên, tôi nhớ bản thân mình đã nói "tại sao tôi phải tìm ra loại biểu thức này mặc dù trình biên dịch có thể suy ra điều này?" trong rất nhiều trường hợp Điều này có thể giúp rất nhiều trong những khoảnh khắc.

Tóm lại:

Mặc dù các tính năng mới của C ++ 11 có vẻ xấu trong cú pháp của họ, tôi nghĩ người ta có thể quen với chúng trong một thời gian ngắn. Mỗi cấu trúc ngôn ngữ mới ban đầu rất khó học; hãy tưởng tượng lần đầu tiên bạn học viết cả một lớp: Đặt khai báo vào tệp tiêu đề, không quên dấu chấm phẩy thừa ở cuối, đặt các định nghĩa vào tệp nguồn, bao gồm cả tệp tiêu đề trong khi đảm bảo rằng nó có bảo vệ để ngăn chặn nhiều vùi, không quên toán tử phân giải phạm vi trong các khai báo hàm thành viên, v.v.

Nhưng tôi khá chắc chắn rằng sau khi viết một vài lớp bạn đã quen với nó và bạn không nghĩ về sự phức tạp của quy trình này: Bởi vì bạn biết rằng một lớp giúp công việc của bạn trở thành một lập trình viên dễ dàng hơn rất nhiều và tiện ích cho bạn thu nhập từ cấu trúc mới này lớn hơn rất nhiều so với mất tiện ích trong thời gian bạn cố gắng học ngôn ngữ . Tôi nghĩ rằng đây có thể là lý do tại sao một người nên cố gắng học hoặc sử dụng C ++ 11 theo cách tương tự.


Các lập luận về tự viết tài liệu và ít cuộn hơn, v.v., tôi khá chắc chắn các đối số ngược lại như "mã lộn xộn", "hạn chế truy cập", v.v ... đã từng được sử dụng để tranh luận tại sao các chức năng bên ngoài lớp phải bị cấm. Tôi nghĩ mọi người cần có thêm kinh nghiệm để quyết định cái nào tốt hơn. Dường như với tôi đây là một thử nghiệm thất bại hoặc một thiết kế tồi. Tôi tin chắc hơn không phải là chuột thí nghiệm trong thí nghiệm này.
Shahbaz

Về cú pháp trông xấu xí, lấy hai ví dụ này: bool is_alive;bool thisSpecialObjectOfMineIsAlive;. Cả hai đều làm như vậy, nhưng thứ hai trông thực sự xấu xí. Tại sao? Bởi vì tôi đã lầm tưởng đưa thêm thông tin làm cho nó rõ ràng hơn, nhưng nó đã làm điều ngược lại. Đó là cùng một thỏa thuận ở đây, Stroustrup có nghĩa là tốt bằng cách cung cấp cho chúng tôi các tính năng, nhưng anh ta đã không làm cho nó đẹp. Đối với tôi điều này cho thấy một thiết kế xấu.
Shahbaz

3
ưa nhìn! = tốt, và xấu! = xấu.
DeadMG

@Shahbaz: Tôi nghĩ lambdas là một khái niệm tuyệt vời (và đã xuất hiện nhiều năm trong các ngôn ngữ như Lisp). Tôi sử dụng chúng rất nhiều trong Haskell. Tôi ít chắc chắn rằng chúng phù hợp với các ngôn ngữ như C ++, Java, v.v. Họ cảm thấy hơi giống với suy nghĩ của tôi: một cái gì đó đã được thêm vào sau bởi vì lambdas đã trở nên phổ biến. Tại sao họ không giới thiệu bằng các ngôn ngữ này ngay từ đầu? Có phải Stroustrup và Goslin chưa bao giờ nghe nói về Lisp?
Giorgio

8

Trên thực tế, OP có một số điểm, như hầu hết các câu trả lời. Nhưng họ "xa" trong tầm nhìn. C.

Đôi khi điều đó xảy ra rằng, sau khi giới thiệu một tính năng mới, một tính năng cũ là cần thiết nữa hoặc cảm thấy mâu thuẫn với nó. Một ngôn ngữ "sạch" nên tự đồng nhất và không cần phải loại bỏ các tính năng cần thiết nữa.

Nhưng thêm vào không phá hủy bất cứ điều gì. Việc xóa (hoặc thay đổi) phá vỡ mã hiện tại vẫn đang được sản xuất, do đó, bất kỳ tính năng nào bạn thêm vào, bạn phải cẩn thận để không phá vỡ mã hiện tại (đặc biệt, không phá vỡ nó một cách im lặng , làm cho nó làm những việc khác như dự định ).

Bạn có phải học tất cả những điều đó? Có, bởi vì tất cả các tính năng là - tốt hay xấu, sớm hay muộn - được sử dụng. Liệu đây có phải là một điều tốt cho "chất lượng" ngôn ngữ (thừa nhận có một thước đo khách quan cho nó) là một câu chuyện khác: khả năng tương thích ngược nên được giữ lại trong bao lâu? khó tìm được câu trả lời, khi ai đó nói 3 năm và một số người khác nói 50.

Cách khác để giữ C ++ "thường xuyên" hơn là ... phá vỡ nó thường xuyên hơn, với khởi động lại đầu. Nhưng nó sẽ không còn C ++ nữa.

Cũng có những nỗ lực để làm điều đó (ví dụ như D, ví dụ: trực giao hơn nhiều so với C ++ (thậm chí 11) thực sự), nhưng chúng phổ biến đến mức nào? Về lý do khó khăn của họ trong việc có động lực là sự không tương thích với nhiều mã hiện có vẫn phải chạy.

C ++ 11, với tôi, rõ ràng là một sự thỏa hiệp giữa nhu cầu mới và khả năng tương thích ngược. Điều đó dẫn đến một "sự lộn xộn" nhất định về thông số kỹ thuật và việc thực hiện. Cho đến khi chi phí cho "sự lộn xộn" đó thấp hơn chi phí không tương thích ... bạn phải rời đi với sự thỏa hiệp đó.

Nếu bạn không thể chịu đựng được nữa, ... tốt hơn là xem xét một ngôn ngữ trẻ hơn. C ++ đơn giản là không thể đơn giản hóa theo nghĩa đó. Không ở tuổi này.


Tôi cũng đồng ý. Và là một nhà phát triển, tôi thấy rất phiền khi có một ngôn ngữ luôn thay đổi (tôi phải học đi học lại). Nếu bạn phát triển một ngôn ngữ mới, bạn nên bắt đầu một ngôn ngữ mới và sử dụng một tên khác. Nếu bạn muốn nó hợp tác với mã kế thừa, có phần tổng hợp riêng cho điều đó. Vì vậy, tôi thực sự không hiểu chính sách thay đổi ngôn ngữ hiện có bằng cách kết hợp các tính năng mới nhất đã trở thành mốt. Như ai đó đã nói: phát triển hơn nữa không tự động ngụ ý tiến bộ.
Giorgio

"C ++ đơn giản là không thể đơn giản hóa theo nghĩa đó. Không phải ở độ tuổi này.": Tại sao không phải là ngôn ngữ lập trình khác (ví dụ C, Ada, ...) đi theo cùng một đường dẫn? Có thể bởi vì họ có sở thích ứng dụng riêng và họ không mong muốn trở thành công cụ cho tất cả các lĩnh vực ứng dụng có thể.
Giorgio

@giorgio: vâng ... có lẽ bạn đúng theo nghĩa "thực dụng". Nhưng trên lý thuyết ... tôi nhớ một số ngày tốt đẹp khi pascal là "ngôn ngữ tham khảo giảng dạy" và ada là "ngôn ngữ lập trình mọi thứ wannabe".
Emilio Garavaglia

Tôi cũng đã học lập trình trong Pascal. Theo như tôi biết thì Ada đã trải qua nhiều lần chỉnh sửa nhưng thiết kế cơ bản của ngôn ngữ không bị lật đổ. Tương tự với C và Pascal. Nếu một người muốn phát triển một ngôn ngữ thực sự mới, một người nên đủ can đảm để thực hiện một cách rõ ràng và bắt đầu một thứ gì đó mới, như D, Java, C #. Vấn đề của tôi với con đường hiện tại mà C ++ đang thực hiện là nó (không cần thiết) trở nên quá phức tạp. Nếu các nguyên tắc KISS và YAGNI áp dụng cho thiết kế phần mềm, tại sao chúng không nên áp dụng cho thiết kế ngôn ngữ lập trình?
Giorgio

@Giorgio: oh ... họ áp dụng ... chính xác như bạn đã nói. Nếu bạn nghĩ C # hoặc D đã lựa chọn tốt hơn C ++ "sôi nổi" (cách giải thích của tôi về cảm giác của bạn), chỉ cần sử dụng chúng thay vì C ++. Một thời gian di chuyển trên C ++ sẽ từ từ chết. Ngay bây giờ, tôi thấy C ++ 11 mang đến một cơ hội mới cho C ++ 03 "luộc" và D vẫn còn thiếu thứ gì đó để phá vỡ rào cản khởi đầu. Lợi ích kinh tế và tập đoàn cũng đóng một vai trò trong cách phát triển được tài trợ và khuyến khích. Bạn đúng về lý thuyết, nhưng thế giới thực phức tạp hơn.
Emilio Garavaglia

7

Ngay cả khi bạn quyết định bỏ qua các tính năng mới của C ++ 11, bạn vẫn sẽ được hưởng lợi từ chúng vì Thư viện chuẩn C ++ sẽ sử dụng chúng. Ví dụ, trong C ++ 98, có một biến loại vector<string>là một thảm họa hiệu suất vì số lượng bản sao cần thiết được tạo ra khi vectơ phát triển. Với hàm tạo di chuyển C ++ 11, đây không phải là vấn đề. Trên thực tế, tôi ước C ++ 11 mang đến cho chúng tôi nhiều tính năng mới, không phải ít hơn - đặc biệt là trong Thư viện tiêu chuẩn.


6

Sau nhiều năm, vẫn còn nhiều người học và viết mã bằng C. Tại sao? Bởi vì ngôn ngữ là tốt.

Đầu tiên, hầu hết sinh viên ngày nay đang học Java hoặc .NET, không phải C. Thứ hai, mọi người vẫn sử dụng C không chỉ vì lợi thế của nó như ngôn ngữ, mà chủ yếu là vì có một lượng lớn phần mềm hiện có được viết bằng C cần được duy trì và mở rộng, và vì trong nhiều trường hợp (ví dụ như các nền tảng nhúng), trình biên dịch C là tất cả. Ngẫu nhiên, đây là một số lý do tại sao mọi người vẫn viết COBOL.

Rất hiếm khi một lập trình viên trong ngành bắt đầu làm việc với một dự án hoàn toàn mới không bị ràng buộc với một cơ sở mã hiện có và tiếp tục làm việc một mình. Vì vậy, lý do để học C ++ 11 là bạn có khả năng phải đối phó với mã được viết bởi người khác, đó là sử dụng các tính năng mới. Ngoài ra, các tính năng đã được thêm vào đã được thêm vào vì một lý do. Một khi bạn học chúng và sử dụng chúng, bạn có thể đến để đánh giá cao chúng.


Bạn trích dẫn câu của tôi không đầy đủ. Giống như tôi đã nói trong câu sau, goodcó nghĩa là nó tuân theo các quy tắc của một thiết kế ngôn ngữ lập trình tốt. Tôi không biết bạn học ở đâu, nhưng tôi biết 4 hoặc 5 quốc gia và tất cả họ đều bắt đầu học lập trình với C. Giống như tôi đã nói, với C, không có trường hợp ngoại lệ nào (điều gì đó trái ngược với Java, bạn hầu như không thể tìm một cấu trúc không có ngoại lệ).
Shahbaz

1
@Shahbaz: Tôi trích dẫn câu hoàn chỉnh. Bạn đã thực hiện một kết nối nhân quả, và tôi nói rằng nó là không đầy đủ nhất. Rất may, tôi không học nữa. :) Tôi đã làm khá đủ điều đó. Tôi sống ở Mỹ và khi tôi học đại học (hơn 15 năm trước) C là ngôn ngữ giới thiệu. Tuy nhiên, ngày nay hầu hết các trường học ở Mỹ đều bắt đầu với Java và không có nhiều lập trình viên trẻ biết C.
Dima

5
@Shahbaz: Tôi thực sự không thấy vấn đề với các quy tắc ngôn ngữ có ngoại lệ. Đúng, C là một ngôn ngữ đơn giản hơn nhiều so với C ++. Mặt khác, C ++ giúp dễ dàng viết mã đơn giản hơn. Để viết mã đơn giản hơn, bạn cần nhiều tính năng ngôn ngữ hơn. Điều đó làm cho ngôn ngữ phức tạp hơn. Tôi, đối với một, như những thứ như các lớp, tài liệu tham khảo, RAII, mẫu, hàm tạo, hàm hủy, ngoại lệ và không gian tên. Nhưng bạn nói rằng câu hỏi của bạn không phải là về C vs C ++, vì vậy tôi đã không viết về câu trả lời đó.
Dima

5
  • Hội được tạo vì mọi người không thích viết mã máy
  • C được tạo ra bởi vì mọi người không thích viết lắp ráp
  • C ++ được tạo ra bởi vì mọi người không thích viết C
  • C ++ 11 được tạo vì mọi người không thích viết C ++

Bạn sẽ đi đến một điểm trong sự nghiệp C ++ của mình, nơi bạn nói với chính mình, "Tôi chắc chắn mong muốn các functor đơn giản hơn" hoặc "Tại sao NULL là một int?" và sau đó bạn sẽ hiểu C ++ 11.


Tất cả các ngôn ngữ đã được tạo vì ai đó không thích những ngôn ngữ hiện có. Điều đó không làm cho bất kỳ người trong số họ tốt.
Shahbaz

Tôi không nói NULLnên là một int. Nó không nên. Điều tôi không thấy phù hợp là giới thiệu một cấu trúc trong ngôn ngữ giải quyết vấn đề này, nhưng đưa ra các ngoại lệ. Họ đáng lẽ có thể làm điều tương tự theo cách tốt hơn.
Shahbaz

2
"C ++ 11 được tạo ra bởi vì mọi người không thích viết C ++": nếu họ không thích viết C ++, tại sao C ++ lại là một tập hợp con của C ++ 11?
Giorgio

1
Nó phải là: C # và Java đã được tạo vì mọi người không thích viết C ++.
Calmarius

4

Học tập luôn có lợi. Kiên thưc la sưc mạnh.

Đó là câu trả lời, về cơ bản. Mọi thứ khác chỉ là chi tiết về việc bạn có thể hưởng lợi chính xác từ nó như thế nào và bạn có quyền hạn gì khi biết nó, và chúng rất nhiều đến nỗi mọi liệt kê sẽ không đầy đủ.

Một ví dụ là câu hỏi của riêng bạn. Bạn thậm chí sẽ không thể hỏi nó mà không học ít nhất một chút về nó.

Và như tôi đã nhận xét - mối quan tâm thực sự không phải là tại sao phải học, mà là tại sao phải sử dụng . Và đó là một câu hỏi hoàn toàn khác.


4

Bạn nên học C ++ 11 vì các tính năng được thêm vào cho phép bạn viết mã tốt hơn. Một số người đã đề cập đến loại an toàn của con trỏ NULL và lambdas, rất đẹp. Nhưng tôi muốn thu hút sự chú ý vào những gì tôi nghĩ là sự thay đổi mạnh mẽ nhất trong C ++ 11, đặc biệt là trong một môi trường sản xuất lớn: di chuyển ngữ nghĩa.

C ++ 11 hỗ trợ các khái niệm riêng biệt về 'di chuyển' và 'sao chép'. Trong C ++ thông thường, chúng ta chỉ có toán tử = về cơ bản thực hiện cả hai điều này. Nhưng thực sự, chúng tôi đang thể hiện hai ý tưởng riêng biệt với một nhà điều hành, điều này rất nguy hiểm.

Ví dụ rõ ràng nhất về nơi điều này hữu ích là unique_ptr mới. Nó có tất cả các tính năng tốt nhất của auto_ptr và scoped_ptr cũ. Giả sử chúng ta muốn có một con trỏ được đảm bảo là con trỏ duy nhất trỏ đến một đối tượng. Làm thế nào để chúng ta đối phó với a = b? Chà, trước đây, chúng tôi đã bị mắc kẹt, bạn có thể không cho phép nó hoàn toàn (như scoped_ptr) hoặc chúng tôi có thể làm những gì auto_ptr làm khi a = b đánh cắp quyền sở hữu từ b. Hành vi này của auto_ptr rất khó hiểu vì a = b thực sự thay đổi b. unique_ptr xử lý việc này: a = b không được phép, nhưng bạn có a = std :: move (b) để đánh cắp quyền sở hữu. Điều này hữu ích như thế nào? Trong đó, có một phiên bản hoán đổi (quá tải) riêng biệt sử dụng ngữ nghĩa di chuyển thay vì sao chép ngữ nghĩa. Điều này có nghĩa là unique_ptr có thể được hoán đổi, không có vấn đề gì. Điều này có nghĩa là unique_ptr, không giống như auto_ptr, là an toàn để sử dụng trong một container và sau đó nói sắp xếp. unique_ptr về cơ bản là tất cả và kết thúc tất cả quản lý bộ nhớ an toàn khi bạn không cần nhiều con trỏ trên cùng một đối tượng.

Một ví dụ tuyệt vời khác: giả sử bạn có một đối tượng không thể phát hiện được. Điều này rất hữu ích trong một số tình huống. Bạn không bao giờ có thể trả lại đối tượng này từ một hàm, bởi vì khi hàm kết thúc, nó sẽ sao chép bất cứ thứ gì bạn đang trả về. Điều trớ trêu là thông thường trình biên dịch thực sự tối ưu hóa điều này (nghĩa là không có gì thực sự được sao chép ở cuối, giá trị trả về được tạo tại địa chỉ của phép gán cuối cùng). Nhưng điều này không liên quan gì đến lý do tại sao chúng tôi làm cho nó không thể phát hiện được; Trả về từ một hàm thực sự chỉ là di chuyển đối tượng từ phạm vi hàm bên trong ra bên ngoài. Bây giờ bạn có thể viết các đối tượng không thể phát hiện được nhưng có thể di chuyển được và các đối tượng này có thể được trả về từ các hàm.

Di chuyển ngữ nghĩa làm cho nó dễ dàng hơn để viết mã mà không bị rò rỉ và là chủ đề an toàn.


Và cũng, bằng cách này, hiệu quả.
Nir Friedman
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.