Sử dụng C ++ nhưng không sử dụng các tính năng cụ thể của ngôn ngữ, có nên chuyển sang C?


16

Tôi đang phát triển trình giả lập NES như một sở thích, trong thời gian rảnh. Tôi sử dụng C ++ vì đây là ngôn ngữ tôi sử dụng chủ yếu, biết hầu hết và thích phần lớn.

Nhưng bây giờ khi tôi thực hiện một số tiến bộ trong dự án, tôi nhận ra rằng tôi không sử dụng hầu hết các tính năng cụ thể của C ++ và có thể đã thực hiện nó trong C đơn giản và nhận được kết quả tương tự. Tôi không sử dụng các mẫu, quá tải toán tử, đa hình, kế thừa. Vậy bạn sẽ nói gì? Tôi nên ở lại C ++ hay viết lại bằng C?

Tôi sẽ không làm điều này để đạt được hiệu suất, nó có thể là một tác dụng phụ, nhưng ý tưởng là tại sao tôi nên sử dụng C ++ nếu tôi không cần nó?

Các tính năng duy nhất của C ++ tôi đang sử dụng là các lớp để đóng gói dữ liệu và phương thức, nhưng điều đó cũng có thể được thực hiện với các cấu trúc và chức năng, tôi đang sử dụng mới và xóa, nhưng cũng có thể sử dụng malloc và miễn phí, và tôi sử dụng tính kế thừa chỉ cho các cuộc gọi lại, có thể đạt được với các con trỏ tới các hàm.

Hãy nhớ rằng, đó là một dự án sở thích, tôi không có thời hạn, vì vậy thời gian và công việc đòi hỏi phải viết lại không phải là một vấn đề, cũng có thể rất vui. Vậy, câu hỏi là C hay C ++?


3
Dường như với tôi rằng bạn đã tự trả lời: tại sao sử dụng C ++ nếu bạn chỉ cần C? Có nhiều tình huống trong đó C hoàn toàn ổn.
Giorgio

3
@Giorgio: Và tất cả đều bốc hơi sau sáu mươi giây đầu tiên và bạn cần duy trì mã của mình.
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.Và đó là câu trả lời cho câu hỏi của bạn. Bạn chỉ nên chuyển đổi ngôn ngữ giữa dự án khi có vấn đề mà ngôn ngữ hiện tại của bạn không thể giải quyết. I don't use templates, operator overloading, polymorphism, inheritance.Việc học và sử dụng các khái niệm sẽ có giá trị hơn nhiều so với việc chuyển sang C. Vì đây là một dự án sở thích, tại sao không sử dụng một vài thứ bạn chưa từng sử dụng trước đây? Bạn luôn có thể bắt đầu một dự án khác trong C và học ngôn ngữ, nhưng đối với dự án hiện tại của bạn, nó không có ý nghĩa để chuyển đổi.
yannis

4
Tôi không sử dụng 100% ngôn ngữ trong mỗi dự án tôi viết. Bạn biết C ++ tốt nhất, bạn có thể tìm thấy những lý do chính đáng để sử dụng các tính năng mà trước đây bạn chưa tìm thấy sử dụng. Bạn có thể bắt đầu điều trị C ++ như một an toàn hơn nhiều C, một khi bạn bắt đầu sử dụng các công cụ thư viện tiêu chuẩn và thúc đẩy các cấu trúc thích std::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::map, vv Đối với chức năng gọi lại, nhìn vào việc sử dụng functors, và trong C ++ 11, bạn cũng có thể bắt đầu sử dụng những thứ như hàm lambda.
wkl

3
@Giorgio: Đúng. Việc cuộn danh sách liên kết infiniteth bị ràng buộc để tạo ra các lỗi không cần thiết.
DeadMG

Câu trả lời:


40

Bạn không sử dụng nó bây giờ, nhưng lần sau khi bạn bị rò rỉ bộ nhớ hoặc có được một đôi xóa, bạn sẽ được xin trở lại std::vector<T>, std::unique_ptr<T, Del>std::shared_ptr<T>, có thể giải quyết những vấn đề easily- gần trivially. Cuối cùng, đó là những gì xảy ra với tất cả những người sử dụng C trên C ++ và những người thông minh hơn chỉ chờ đợi các lỗi xuất hiện trước khi chuyển qua.

Mã sử ​​dụng newdeletetrực tiếp không thực sự thuộc về C ++, nó thuộc loại nửa nhà mà chúng ta gọi là "C với các lớp". Đó là nơi ngôn ngữ được sử dụng vào khoảng năm 1985. Nó không đặc biệt giống với C ++, vào khoảng năm 2011. Trong mọi khả năng, bất cứ nơi nào bạn học C ++ chỉ đơn giản là không dạy nó rất tốt - một điều không may là khá phổ biến - và với một nền giáo dục tốt hơn, bạn sẽ tìm sử dụng các tính năng này.

Cụ thể, như tôi đã liệt kê ở trên, các cấu trúc dữ liệu chung của C ++ và các lớp quản lý tài nguyên đơn giản là vượt trội về cơ bản so với bất cứ thứ gì C cung cấp. Nếu bạn muốn một mảng được phân bổ động, sau đó sử dụng std::vector<T>. Đó là một trường hợp sử dụng khá phổ biến. Nếu bạn không sử dụng chúng, thì mã của bạn có nguy cơ lỗi rất lớn không cần thiết - đặc biệt là liên quan đến quản lý tài nguyên. C ++ có thể đảm bảo an toàn và sử dụng lại mã theo cách mà C không bao giờ có thể chạm vào.

Tuy nhiên, tôi nghĩ rằng bạn cũng có thể mong đợi quá nhiều. Viết mẫu và quá tải toán tử không phổ biến đối với người tiêu dùng thư viện. Nếu mã của bạn sử dụng std::vector<T>, bạn không cần phải viết một mẫu để thực hiện điều đó. Nếu mã của bạn sử dụng std::string, không ai buộc bạn phải quá tải toán tử. Bạn chỉ phải làm những điều đó để viết std::vector<T>std::string- nhưng bạn vẫn có thể tận dụng tối đa chúng.

Đa hình / kế thừa cũng chỉ có một trường hợp sử dụng cụ thể. Nếu mã của bạn xảy ra không yêu cầu bạn viết bất kỳ mẫu nào hoặc sử dụng các hàm ảo, thì nó không có, và có các chương trình hoặc phân đoạn chương trình mà bạn không cần phải viết mẫu của riêng mình.

Ngoài ra, không có hiệu suất trong C so với C ++.


1
@Giorgio: make_sharedtồn tại và bạn có thể viết một make_uniquemẫu tầm thường thực hiện cùng một công việc. An toàn hơn.
DeadMG

4
Câu trả lời chính xác. Đinh trên đầu. C ++ có giá trị nhất đối với các thư viện nhỏ mà chúng ta nên luôn luôn sử dụng.
Andres Jaan Tack

2
@Giorgio: Không an toàn vì khi gọi nhiều đối số như vậy, bạn có thể bị rò rỉ bộ nhớ trong trường hợp ngoại lệ và make_sharedhiệu quả hơn. Chỉ có chức năng nhà máy có thể cung cấp an toàn ngoại lệ được đảm bảo.
DeadMG

6
@ tp1: WTF? Bằng tiếng Anh, xin vui lòng.
DeadMG

2
@Lohoris Bạn không cần một trích dẫn cho lẽ thường. Theo cách nào thì C nên hoạt động tốt hơn C ++?
Chris nói Phục hồi lại

7

Ngay cả khi bạn không sử dụng các tính năng cụ thể của C ++, trình biên dịch C ++ sẽ gặp nhiều vấn đề hơn so với C do hệ thống loại C ++ chặt chẽ hơn.


6

Tôi sẽ nhìn nó từ hướng khác. Bạn sẽ đạt được bất cứ điều gì bằng cách viết lại mã trong C? Ngay cả trong một dự án hoàn toàn sở thích, có một chi phí liên quan đến việc viết lại như thế. Nếu không có gì khác, thứ mà tôi cho là sẽ được gọi là chi phí cơ hội - tức là, những thứ khác bạn có thể đã làm trong thời gian đó nếu bạn không lãng phí thời gian để viết lại nó trong C.

Điểm mấu chốt: trừ khi bạn nghĩ rằng mã thực sự có khả năng được sử dụng trong một số môi trường nơi quyền truy cập vào C ++ thực sự bị hạn chế (hoặc không tồn tại), thì sẽ rất lãng phí thời gian vô ích. Ít nhất là theo kinh nghiệm của tôi, nó thường vượt xa rất nhanh - nghĩ lại về mã tôi đã viết bằng C ++ phải chuyển đổi thành C, tôi có thể nhớ khá rõ rằng ngay cả trong một vài trường hợp có vẻ như thật là tầm thường, tôi đã sử dụng rất nhiều tính năng dành riêng cho C ++ so với lúc đầu tôi nhận ra. Để có nhiều hy vọng hữu ích, bạn sẽ phải nhắm mục tiêu C89 / 90, trong trường hợp đó, bạn sẽ nhanh chóng được nhắc nhở về những việc như phải xác định tất cả các biến ở đầu một khối thay vì thực sự chúng là gì đã sử dụng.

Nói tóm lại, trừ khi bạn khá chắc chắn viết lại bằng C sẽ mang lại lợi ích thực sự, gần như chắc chắn sẽ có rất nhiều điều tốt hơn để làm.


+1 Cách đây một thời gian, tôi đã phải viết một thư viện để sử dụng trong một dự án C khác và tôi nghĩ rằng đó cũng là một ý tưởng tốt để thực hiện nó trong C, đó là một thằng ngốc ngu ngốc mà tôi đã trở lại sau đó.
Chris nói Phục hồi lại

1

Như một câu trả lời tổng quát hơn:

Đừng chuyển sang C ++ chỉ vì bạn đang sử dụng một số tính năng độc đáo hơn. Một ngày nào đó bạn có thể cần những tính năng đó, và sẽ chỉ đập đầu vì bạn đang sử dụng C.


1

Để phát triển sở thích, tôi sẽ xem xét chuyển trở lại ngôn ngữ C. C và C đơn giản có nhiều khả năng được hỗ trợ trên các mô-đun phát triển sở thích nhỏ.

Nhiều câu trả lời ở đây có thể là từ các loại phần mềm chuyên nghiệp. Là người có sở thích, bạn sẽ không được mã hóa liên tục hoặc toàn thời gian. Vì vậy, hãy xem xét ngôn ngữ nào bạn có khả năng nhớ hoặc quên những điều kỳ quặc bên trong, nếu bạn đặt dự án của mình trong một năm và sau đó quay lại và cố gắng đọc mã của bạn sau khi bạn đã bị mã hóa. C ++, có bộ tính năng phong phú hơn, có thể mất nhiều thời gian hơn để có được lại, tùy thuộc vào phong cách mã hóa của bạn.


1

Thật không dễ để trả lời câu hỏi của bạn, vì chúng tôi không biết liệu bạn đang làm việc trong dự án để cải thiện các kỹ năng cụ thể về ngôn ngữ của bạn (C vs C ++) hay để cải thiện các kỹ năng lập trình khác (thiết kế, giải quyết vấn đề, v.v.).

"Các tính năng duy nhất của C ++ tôi đang sử dụng là các lớp để đóng gói dữ liệu và phương thức, nhưng điều đó có thể được thực hiện tốt với các cấu trúc và chức năng,". Đây không phải là sự thật. structstrong C không hỗ trợ đóng gói và không thể chứa hàm (phương thức) - ít nhất là không sử dụng các kỹ thuật như con trỏ tới hàm. Ngoài ra, các chức năng trong C yếu hơn vì chúng không thể bị quá tải.

"Tôi đang sử dụng mới và xóa, nhưng cũng có thể sử dụng malloc và miễn phí, và tôi đang sử dụng tính kế thừa chỉ cho các cuộc gọi lại, điều này có thể đạt được với các con trỏ tới các chức năng." Như deadmg đã đề cập, sử dụng trực tiếp newdeletetrong C ++ không được khuyến khích. Ngoài ra, kế thừa IMHO (và GoF) trong OOP chỉ nên được ưu tiên hơn thành phần khi cần đa hình. Và tôi không nghĩ rằng việc đạt được tính đa hình (liên kết muộn) trong C là không quan trọng bằng cách sử dụng các con trỏ tới các hàm.

Ngoài ra, tôi sẽ không thuyết phục bạn rằng C ++ "tốt" hơn C vì đó là vấn đề ưu tiên và nó luôn phụ thuộc vào vấn đề mà bạn đang cố gắng giải quyết (sử dụng các tính năng OOP để phát triển trình giả lập NES của bạn một ý tưởng tốt).


1
structstrong C, trên thực tế, có thể được sử dụng để đóng gói các phương thức. Bạn chỉ cần tạo một cấu trúc của các con trỏ hàm và khởi tạo chúng để trỏ đến bất kỳ hàm nào bạn muốn. Hãy xem lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 để biết ví dụ.
Robert Martin

Đúng rồi. Cảm ơn các bình luận, tôi mở rộng câu trả lời.
sakisk

Đẹp. Thêm một nit: các hàm trong C có thể bị quá tải (nghĩ printf), nhưng khi làm như vậy bạn sẽ mất bất kỳ loại kiểm tra nào. Không có cách nào để có một bộ khai báo hữu hạn có thể chấp nhận: đó là 1 (và bạn có thể kiểm tra loại) hoặc "nhiều" (và mất tất cả kiểm tra loại, có nguy cơ cá nhân rất lớn). Như với hầu hết mọi thứ trong C, nó có thể nhưng thường không thoải mái.
Robert Martin

Con trỏ đến các chức năng là một kỹ thuật C tiên tiến? Có thật không?
Donal Fellows

@DonalFellows Bạn nói đúng, tôi phóng đại. Đã xóa nâng cao ... :)
sakisk

0

Tôi là một người mới bắt đầu, vì vậy đây là 2 bit của tôi.

Tôi đang học C và C ++ tại Wibit.net với một số băng video cơ bản đẹp, có lẽ chúng có thể giúp bạn rất nhiều để có cái nhìn tổng quan về "tình huống" (không phải quảng cáo!)

Tôi khuyên bạn nên đổi sang C, chỉ để học, vì bạn là người có sở thích, đây sẽ là một niềm vui chứ không phải là vấn đề.

Tôi tư vấn thêm. Làm điều đó bằng cả hai ngôn ngữ. So sánh cách và giải pháp bạn sẽ tìm và sử dụng. Tôi chắc chắn rằng nó sẽ không "dễ dàng" như bạn mong đợi ... nhưng chắc chắn bạn sẽ học được rất nhiều!


1
Cảm ơn bạn rất nhiều, nhưng tôi không học, tôi đã biết C và C ++, tôi đang hỏi nên dùng cái nào cho dự án cụ thể này.
Petruza

Rất tiếc, thời gian của tôi để tìm hiểu! = P
H_7

1
Ngoài ra, tôi sẽ khuyên rằng thay vì hướng dẫn bằng video, bạn hãy lấy sách của Kernigan và Stroustrup, một IDE đẹp (Visual Studio, Eclipse, Xcode) và học bằng cách mã hóa các ví dụ, dùng thử và lỗi và dùng đến stackoverflow.
Petruza

-1

Dưới đây là ưu và nhược điểm của C ++ so với C:

  1. Di chuyển đến C sẽ giúp dễ dàng hơn trong tập hợp con C ++ đã chọn, bởi vì trình biên dịch sẽ báo lỗi khi bạn đi ra ngoài nó. Nếu vấn đề chính là ở lại trong tập hợp con quyết định, nên chọn phương án này. (tại sao chúng tôi không có hỗ trợ trình biên dịch cho việc này?)
  2. Một khi bạn có thể ở trong tập hợp tính năng c ++ đã chọn, thì điều tiếp theo là cố gắng thay đổi tập hợp con để loại bỏ các quy ước xấu phá vỡ mã. Điều này đòi hỏi phải sử dụng toàn bộ c ++.
  3. Khi bạn có cả "nằm trong tập hợp con" và "đó là tập hợp con tốt", sau đó di chuyển ra ngoài các tính năng của c ++ và bắt đầu suy nghĩ về các yêu cầu.
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.