ใช้ C ++ แต่ไม่ได้ใช้คุณสมบัติเฉพาะของภาษาควรเปลี่ยนเป็น C?


16

ฉันกำลังพัฒนาตัวจำลอง NES เป็นงานอดิเรกในเวลาว่าง ฉันใช้ C ++ เพราะเป็นภาษาที่ฉันใช้เป็นส่วนใหญ่รู้จักเป็นส่วนใหญ่และชอบมากที่สุด

แต่ตอนนี้ฉันก้าวไปข้างหน้าในโครงการฉันรู้ว่าฉันไม่ได้ใช้คุณสมบัติเฉพาะของ C ++ และสามารถทำได้ใน C ธรรมดาและรับผลลัพธ์เดียวกัน ฉันไม่ได้ใช้เทมเพลตการใช้งานอุปกรณ์มากเกินไปความหลากหลายรูปแบบการสืบทอด แล้วคุณจะว่าอย่างไร ฉันควรอยู่ใน C ++ หรือเขียนใหม่ใน C?

ฉันจะไม่ทำสิ่งนี้เพื่อเพิ่มประสิทธิภาพมันอาจมาเป็นผลข้างเคียง แต่ความคิดก็คือทำไมฉันต้องใช้ C ++ ถ้าฉันไม่ต้องการมัน?

คุณลักษณะเฉพาะของ C ++ ที่ฉันใช้คือคลาสเพื่อห่อหุ้มข้อมูลและวิธีการ แต่ก็สามารถทำได้เช่นกันกับ structs และฟังก์ชั่นฉันใช้ใหม่และลบ แต่ก็สามารถใช้ malloc และฟรีและฉัน ใช้การสืบทอดสำหรับการเรียกกลับซึ่งสามารถทำได้ด้วยตัวชี้ไปยังฟังก์ชัน

โปรดจำไว้ว่ามันเป็นโครงการงานอดิเรกฉันไม่มีกำหนดเวลาดังนั้นค่าใช้จ่ายและงานที่ต้องมีการเขียนใหม่ไม่ใช่ปัญหาอาจสนุกเช่นกัน ดังนั้นคำถามคือ C หรือ C ++


3
ดูเหมือนว่าคุณได้ตอบตัวเองแล้ว: ทำไมต้องใช้ C ++ ถ้าคุณต้องการ C เท่านั้น มีหลายสถานการณ์ที่ C ใช้ได้อย่างสมบูรณ์
Giorgio

3
@Giorgio: และพวกเขาทั้งหมดระเหยหลังจากหกสิบวินาทีแรกและคุณจำเป็นต้องรักษารหัสของคุณ
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.และนั่นคือคำตอบสำหรับคำถามของคุณ คุณควรเปลี่ยนภาษากลางโปรเจ็กต์เมื่อเกิดปัญหาที่ภาษาปัจจุบันของคุณไม่สามารถแก้ไขได้ I don't use templates, operator overloading, polymorphism, inheritance.มันจะมีค่ามากขึ้นในการเรียนรู้และใช้แนวคิดมากกว่าการเปลี่ยนเป็น C เนื่องจากนี่เป็นโครงการงานอดิเรกทำไมไม่ใช้บางสิ่งที่คุณไม่เคยใช้มาก่อน คุณสามารถเริ่มต้นโครงการใหม่ใน C และเรียนรู้ภาษาได้ตลอด แต่สำหรับโครงการปัจจุบันของคุณมันไม่เหมาะสมที่จะเปลี่ยน
yannis

4
ฉันไม่ได้ใช้ภาษา 100% ในทุกโครงการที่ฉันเขียน คุณรู้จัก C + + ที่ดีที่สุดคุณอาจพบเหตุผลที่ดีในการใช้คุณสมบัติที่คุณไม่เคยพบมาก่อน คุณสามารถเริ่มต้นการรักษา C ++ เป็นที่ปลอดภัยมาก C, เมื่อคุณเริ่มใช้สิ่งที่ห้องสมุดมาตรฐานและสร้างเพิ่มชอบstd::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::mapฯลฯ สำหรับฟังก์ชั่นการโทรกลับมองในการใช้ functors และใน C ++ 11 คุณ ยังสามารถเริ่มใช้สิ่งต่าง ๆ เช่นฟังก์ชั่นแลมบ์ดา
wkl

3
@Giorgio: ใช่ การกลิ้งรายการเชื่อมโยงอินฟินิทนั้นถูกผูกไว้เพื่อสร้างข้อผิดพลาดที่ไม่จำเป็น
DeadMG

คำตอบ:


40

คุณไม่ได้ใช้มันในขณะนี้ แต่ครั้งต่อไปคุณหน่วยความจำรั่วหรือได้รับคู่ลบคุณจะได้รับขอทานที่จะกลับไปมาstd::vector<T>, std::unique_ptr<T, Del>และstd::shared_ptr<T>ซึ่งสามารถแก้ปัญหาเหล่านั้น easily- เกือบนิด นั่นคือสิ่งที่เกิดขึ้นกับทุกคนที่ใช้ C มากกว่า C ++ ในที่สุดและคนที่ฉลาดกว่าก็ไม่รอให้บั๊กปรากฏขึ้นก่อนที่จะย้ายไป

รหัสที่ใช้newและdeleteไม่ได้อยู่ใน C ++ โดยตรงจริง ๆ มันเป็นของบ้านครึ่งหนึ่งที่เราเรียกว่า "C กับคลาส" นั่นคือที่ที่ภาษาประมาณปี 1985 มันไม่คล้ายกับ C ++ โดยประมาณปี 2011 ในทุกโอกาสที่คุณเรียนรู้ C ++ เพียงแค่ไม่ได้สอนมันอย่างดี - สิ่งที่น่าเสียดายที่ค่อนข้างสามัญ - และด้วยการศึกษาที่ดีกว่าคุณจะค้นหาการใช้คุณสมบัติเหล่านี้

โดยเฉพาะอย่างยิ่งที่ฉันได้กล่าวไว้ข้างต้นโครงสร้างข้อมูลทั่วไปของ C ++ และคลาสการจัดการทรัพยากรนั้นเรียบง่ายกว่าสิ่งที่ C มีให้ std::vector<T>หากคุณต้องการอาร์เรย์จัดสรรแล้วใช้ เป็นกรณีการใช้งานที่ค่อนข้างธรรมดา หากคุณไม่ได้ใช้งานรหัสของคุณมีความเสี่ยงสูงที่จะเกิดข้อผิดพลาดโดยไม่จำเป็นโดยเฉพาะอย่างยิ่งการจัดการทรัพยากรที่เกี่ยวข้อง C ++ สามารถรับประกันความปลอดภัยและนำรหัสกลับมาใช้ใหม่ในวิธีที่ C ไม่สามารถสัมผัสได้

อย่างไรก็ตามฉันคิดว่าคุณอาจคาดหวังมากเกินไป การเขียนเทมเพลตและตัวดำเนินการโอเวอร์โหลดนั้นไม่ใช่เรื่องปกติสำหรับผู้บริโภคในห้องสมุด หากรหัสของคุณใช้std::vector<T>คุณไม่จำเป็นต้องเขียนแม่แบบเพื่อให้เกิดขึ้น หากรหัสของคุณใช้std::stringไม่มีใครบังคับให้คุณโอเวอร์โหลดโอเปอเรเตอร์ของคุณ คุณต้องทำสิ่งเหล่านั้นเพื่อเขียน std::vector<T>และstd::string- แต่คุณยังสามารถใช้ประโยชน์จากพวกเขาได้อย่างเต็มที่

ความแตกต่าง / การสืบทอดยังมีเฉพาะกรณีการใช้งานเท่านั้น หากรหัสของคุณไม่ต้องการให้คุณเขียนเทมเพลตใด ๆ หรือใช้ฟังก์ชั่นเสมือนจริงก็ไม่จำเป็นและมีโปรแกรมหรือส่วนของโปรแกรมที่คุณไม่จำเป็นต้องเขียนเทมเพลตของคุณเอง

นอกจากนี้ยังไม่มีการเพิ่มประสิทธิภาพใน C มากกว่า C ++


1
@Giorgio: make_sharedมีอยู่และคุณสามารถเขียนmake_uniqueเทมเพลตเล็กน้อยที่ทำงานเดียวกันได้ มันปลอดภัยกว่า
DeadMG

4
คำตอบที่ดี เล็บบนหัว C ++ มีค่ามากที่สุดสำหรับไลบรารี่เล็ก ๆ ที่เราควรใช้อยู่เสมอ
Andres Jaan Tack

2
@Giorgio: มันไม่ปลอดภัยเพราะเมื่อมีการเรียกอาร์กิวเมนต์หลาย ๆ อย่างเช่นนั้นคุณสามารถทำให้หน่วยความจำรั่วในกรณีที่มีข้อยกเว้นและmake_sharedมีประสิทธิภาพมากกว่า เฉพาะฟังก์ชั่นจากโรงงานเท่านั้นที่สามารถให้ข้อยกเว้นด้านความปลอดภัยที่รับประกันได้
DeadMG

6
@ tp1: WTF หรือไม่ เป็นภาษาอังกฤษ.
DeadMG

2
@ โลฮาริสคุณไม่จำเป็นต้องมีการอ้างถึงสามัญสำนึก C ควรมีประสิทธิภาพมากกว่า C ++ อย่างไร?
คริสพูดว่า Reinstate Monica

7

แม้ว่าคุณจะไม่ได้ใช้คุณสมบัติเฉพาะของ C ++ ก็ตามคอมไพเลอร์ C ++ จะตรวจพบปัญหามากกว่า C หนึ่งเนื่องจากระบบประเภทที่เข้มงวดกว่าของ C ++


6

ฉันจะดูจากทิศทางอื่น คุณจะได้อะไรจากการเขียนโค้ดใน C หรือไม่? แม้แต่ในโครงการงานอดิเรกล้วนๆ แต่ก็มีค่าใช้จ่ายที่เกี่ยวข้องกับการเขียนซ้ำเช่นนั้น หากไม่มีสิ่งใดที่ฉันคิดว่าจะมีค่าใช้จ่ายโอกาส - กล่าวคือสิ่งอื่น ๆ ที่คุณสามารถทำได้ในเวลานั้นถ้าคุณไม่เสียเวลาเขียนมันใหม่ในซี

บรรทัดล่างสุด: หากคุณคิดว่ารหัสมีแนวโน้มที่จะถูกนำมาใช้จริงในบางสภาพแวดล้อมที่การเข้าถึง C ++ มี จำกัด (หรือไม่มีอยู่จริง) มันจะเป็นการเสียเวลาอย่างไร้จุดหมายอย่างดีที่สุด อย่างน้อยในประสบการณ์ของฉันมันมักจะไปได้ดีกว่าอย่างรวดเร็ว - คิดถึงโค้ดที่ฉันเขียนในภาษาซีพลัสพลัสต้องถูกแปลงเป็น C ฉันสามารถจำได้อย่างชัดเจนว่าแม้ในบางกรณีที่ดูเหมือน มันควรจะเป็นเรื่องเล็กน้อยฉันใช้คุณสมบัติเพิ่มเติมเฉพาะกับ C ++ มากกว่าที่ฉันรู้ในตอนแรก เพื่อให้มีความหวังมากในการเป็นประโยชน์เลยคุณจะต้องกำหนดเป้าหมาย C89 / 90 ซึ่งในกรณีนี้คุณจะได้รับการเตือนอย่างรวดเร็วเกี่ยวกับสิ่งต่าง ๆ เช่นต้องกำหนดตัวแปรทั้งหมดที่จุดเริ่มต้นของบล็อกแทนที่จะเป็นที่ที่จริงแล้ว ใช้

ในระยะสั้นยกเว้นว่าคุณค่อนข้างมั่นใจว่าการเขียนใหม่ใน C จะให้ประโยชน์ที่แท้จริงมีหลายสิ่งที่ต้องทำ


+1 บางครั้งก่อนหน้านี้ฉันต้องเขียนห้องสมุดเพื่อใช้ในโครงการ C อีกโครงการและฉันคิดว่ามันเป็นความคิดที่ดีที่จะนำไปใช้กับ C ด้วยเช่นกันคนที่โง่งี่เง่าที่ฉันกลับมาตอนนั้น
คริสพูดว่า Reinstate Monica

1

เป็นคำตอบทั่วไปเพิ่มเติม:

อย่าเปลี่ยนเป็น C ++ เพียงเพราะคุณใช้คุณสมบัติบางอย่างที่เป็นเอกลักษณ์มากขึ้น วันหนึ่งคุณอาจต้องใช้ฟีเจอร์เหล่านั้นและจะทำให้หัวของคุณสั่นเพราะคุณกำลังใช้ C


1

สำหรับการพัฒนางานอดิเรกฉันจะพิจารณาเปลี่ยนกลับไปเป็นภาษาธรรมดา C และภาษา C เหมือนมีแนวโน้มที่จะได้รับการสนับสนุนในโมดูลการพัฒนางานอดิเรกขนาดเล็ก

คำตอบมากมายที่นี่อาจมาจากซอฟต์แวร์ประเภทมืออาชีพ ในฐานะนักอดิเรกคุณจะไม่ได้รับการเข้ารหัสอย่างต่อเนื่องหรือเต็มเวลา ดังนั้นพิจารณาภาษาที่คุณมีแนวโน้มจะจดจำหรือลืมความแปลกประหลาดภายในหากคุณจัดตารางโครงการของคุณเป็นเวลาหนึ่งปีจากนั้นกลับมาลองอ่านโค้ดของคุณหลังจากที่คุณมีสนิมในการเขียนโปรแกรม C ++ ซึ่งมีชุดคุณลักษณะที่สมบูรณ์ยิ่งขึ้นอาจใช้เวลามากขึ้นหรือน้อยลงในการได้รับอีกครั้งขึ้นอยู่กับสไตล์การเข้ารหัสของคุณ


1

การตอบคำถามของคุณไม่ใช่เรื่องง่ายเนื่องจากเราไม่รู้ว่าคุณกำลังทำโครงงานเพื่อพัฒนาทักษะภาษาเฉพาะของคุณ (C vs C ++) หรือเพื่อพัฒนาทักษะการเขียนโปรแกรมอื่น ๆ (การออกแบบการแก้ปัญหาและอื่น ๆ )

"คุณสมบัติเดียวของ C ++ ที่ฉันใช้คือคลาสเพื่อห่อหุ้มข้อมูลและวิธีการ แต่ก็สามารถทำได้เช่นกันกับ structs และฟังก์ชั่น" นี่ไม่เป็นความจริง. structsใน C ไม่สนับสนุนการห่อหุ้มและไม่สามารถมีฟังก์ชั่น (เมธอด) - อย่างน้อยไม่ได้โดยไม่ต้องใช้เทคนิคเช่นตัวชี้ไปยังฟังก์ชั่น นอกจากนี้ฟังก์ชั่นใน C นั้นอ่อนแอกว่าเพราะไม่สามารถโหลดได้มากเกินไป

"ฉันใช้ใหม่และลบ แต่สามารถใช้ malloc และฟรีได้และฉันใช้การสืบทอดสำหรับการโทรกลับซึ่งสามารถทำได้ด้วยตัวชี้ไปยังฟังก์ชัน" ดังที่กล่าวถึง deadmg, การใช้โดยตรงnewและdeleteใน C ++ ไม่ได้รับการสนับสนุน นอกจากนี้ควรเลือกใช้การสืบทอด IMHO (และ GoF) ใน OOP เหนือการจัดองค์ประกอบเฉพาะเมื่อจำเป็นต้องมีหลายรูปแบบ และฉันไม่คิดว่ามันเป็นเรื่องไม่สำคัญที่จะบรรลุความแตกต่าง (การผูกปลาย) ใน C โดยใช้พอยน์เตอร์กับฟังก์ชั่น

นอกเหนือจากนั้นฉันจะไม่พยายามโน้มน้าวคุณว่า C ++ เป็น "ดีกว่า" เพราะมันเป็นเรื่องของความชอบและมันก็ขึ้นอยู่กับปัญหาที่คุณพยายามแก้อยู่เสมอ (การใช้คุณสมบัติ OOP เพื่อพัฒนาตัวจำลอง NES ของคุณอาจเป็น ความคิดที่ดี).


1
structsในความเป็นจริง C สามารถนำมาใช้เพื่อห่อหุ้มวิธีการ คุณเพียงสร้างโครงสร้างของพอยน์เตอร์ของฟังก์ชั่นและกำหนดค่าเริ่มต้นให้ชี้ไปที่ฟังก์ชันที่คุณต้องการ ลองดูที่lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598เพื่อดูตัวอย่าง
Robert Martin

ถูกตัอง. ขอบคุณสำหรับความคิดเห็นที่ฉันขยายคำตอบ
sakisk

ดี อีกหนึ่ง nit: ฟังก์ชันใน C สามารถโอเวอร์โหลดได้ (คิดprintf) แต่ในการทำเช่นนั้นคุณจะสูญเสียการตรวจสอบทุกประเภท ไม่มีวิธีใดที่จะมีชุดการประกาศที่ยอมรับได้อย่าง จำกัด : มันเป็น 1 (และคุณได้รับการตรวจสอบประเภท) หรือ "หลายคน" (และการตรวจสอบทุกประเภทหายไปและมีความเสี่ยงสูง) เช่นเดียวกับสิ่งต่างๆใน C เป็นไปได้แต่มักจะรู้สึกไม่สบายใจ
Robert Martin

ตัวชี้ไปยังฟังก์ชั่นเป็นเทคนิค C ขั้นสูง? จริงๆ?
Donal Fellows

@ DonalFellows คุณพูดถูกฉันพูดเกินจริง ลบขั้นสูง ... :)
sakisk

0

ฉันเป็นผู้เริ่มต้นมากดังนั้นนี่คือ 2 บิตของฉัน

ฉันกำลังเรียนรู้ C และ C ++ ที่ Wibit.net กับ videotutorials ขั้นพื้นฐานที่ดีบางทีพวกเขาสามารถช่วยคุณได้มากในการดูภาพรวมของ "สถานการณ์" (ไม่ใช่โฆษณา!)

ฉันแนะนำให้คุณเปลี่ยนเป็น C เพื่อเรียนรู้ในขณะที่คุณเป็นนักอดิเรกนี่จะเป็นความสุขไม่ใช่ปัญหา

ฉันแนะนำเพิ่มเติม ทำได้ทั้งสองภาษา เปรียบเทียบวิธีและโซลูชันที่คุณจะพบและใช้งาน ฉันแน่ใจว่ามันจะไม่ "ง่าย" อย่างที่คุณคาดหวัง ... แต่แน่นอนว่าคุณจะได้เรียนรู้มากมาย!


1
ขอบคุณมาก แต่ฉันไม่ได้เรียนรู้ฉันรู้ C และ C ++ แล้วฉันขอให้ใช้อันไหนสำหรับโครงการนี้โดยเฉพาะ
Petruza

อ๊ะเวลาของฉันที่จะเรียนรู้! = P
H_7

1
นอกจากนี้ฉันอยากจะแนะนำว่าแทนที่จะเป็นแบบฝึกหัดวิดีโอคุณจะได้รับหนังสือของ Kernigan และ Stroustrup IDE ที่ดี (Visual Studio, Eclipse, Xcode) และเรียนรู้โดยการเข้ารหัสตัวอย่างการทดลองและข้อผิดพลาด
Petruza

-1

นี่คือข้อดีข้อเสียของ C ++ กับ C:

  1. การย้ายไปที่ C จะทำให้อยู่ภายในชุดย่อย C ++ ที่เลือกได้ง่ายขึ้นเนื่องจากคอมไพเลอร์จะให้ข้อผิดพลาดเมื่อคุณออกไปข้างนอก หากปัญหาหลักเกิดขึ้นกับการอยู่ภายในชุดย่อยที่เลือกควรเลือกทางเลือกนี้ (ทำไมเราถึงไม่มีคอมไพเลอร์สนับสนุนสิ่งนี้)
  2. เมื่อคุณสามารถอยู่ในชุดย่อยของคุณสมบัติ c ++ ที่เลือกไว้แล้วสิ่งต่อไปคือพยายามเปลี่ยนชุดย่อยเพื่อกำจัดข้อตกลงที่ไม่ดีซึ่งทำลายรหัส สิ่งนี้ต้องการการใช้งานทั้ง c ++
  3. เมื่อคุณมีทั้ง "อยู่ในชุดย่อย" และ "เป็นชุดย่อยที่ดี" จากนั้นย้ายออกนอกฟีเจอร์ c ++ และเริ่มคิดถึงข้อกำหนด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.