เราควรหลีกเลี่ยงคุณสมบัติภาษาที่ C ++ มี แต่ Java ไม่ได้หรือไม่


110

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

ฉันคิดว่าเหตุผลคือ:

  1. เนื่องจาก Java เป็นรุ่นใหม่กว่า C ++ หาก Java ไม่มีคุณสมบัติที่ C ++ มีหมายความว่าคุณลักษณะนั้นไม่ดีดังนั้นเราจึงควรหลีกเลี่ยงการใช้งาน
  2. รหัส C ++ พร้อมคุณสมบัติเฉพาะ C ++ (เช่น: ฟังก์ชั่นเพื่อนหลายมรดก) สามารถดูแลรักษาหรือตรวจสอบโดยโปรแกรมเมอร์ C ++ เท่านั้น แต่ถ้าเราเขียน C ++ เช่น Java (โดยไม่มีคุณสมบัติเฉพาะภาษา C ++) โค้ดนั้นสามารถรักษาหรือตรวจสอบได้โดยทั้งสอง โปรแกรมเมอร์ C ++ และ Java
  3. คุณอาจถูกขอให้แปลงรหัสเป็น Java ในบางวัน
  4. รหัสที่ไม่มีคุณสมบัติเฉพาะ C ++ มักจะสามารถบำรุงรักษาได้มากกว่า
  5. คุณลักษณะเฉพาะภาษา C ++ ทุกตัว (เช่น: การสืบทอดหลายอย่าง) ควรมีทางเลือกที่จะนำไปใช้ใน Java หากไม่เป็นเช่นนั้นหมายความว่ารูปแบบการออกแบบหรือสถาปัตยกรรมรหัสเป็นปัญหา

มันเป็นเรื่องจริงเหรอ?


7
หากคุณดูคำแนะนำของคุณคุณกำลังพูดถึงการสร้างมาตรฐานการเข้ารหัส ความจริงที่ว่าคุณกำลังสร้างและปฏิบัติตามมาตรฐานเป็นจริงสิ่งที่จะเพิ่มการบำรุงรักษา
Brandin

63
รหัส Java ควรถูก จำกัด ด้วยคุณสมบัติที่พบในภาษา C ++ ด้วยหรือไม่ ดังนั้นอย่าใช้ตัวอย่างเช่น Java volatile, การเข้าถึงสมาชิกคลาส - แพคเกจส่วนตัว, การสะท้อน / การวิปัสสนา, บล็อกสุดท้าย, ข้อยกเว้นที่ตรวจสอบ, และอื่น ๆ ? คำถามทั้งหมดไม่สมเหตุสมผล ... C ++ และ Java มีความคล้ายคลึงกันเล็กน้อย แต่ท้ายที่สุดแล้วภาษาที่แตกต่างกันมาก
hyde

5
ภาษาจะพัฒนาได้อย่างไรหากผู้คนไม่ต้องการใช้คุณสมบัติใหม่ จุดประสงค์ของฟีเจอร์ใหม่คือการทำให้ชีวิตของคุณง่ายขึ้นโดยการแก้ปัญหาทั่วไป หากผู้ใช้ไม่ใช้คุณสมบัติใหม่แสดงว่าไม่มีแรงจูงใจให้ทุกคนนำไปใช้
Matthew

72
หากคุณต้องการ Java ให้ใช้ Java หากคุณใช้ C ++ ให้ใช้ C ++ ไม่ใช่การเลียนแบบ twisted ที่น่ากลัวและบิดเบี้ยวของ Java ด้วย C ++ การใช้ C ++ แต่การ จำกัด ตัวเองให้เข้ากับชุดคุณลักษณะของ Java จะทำให้คุณแย่ที่สุดในโลกทั้งสอง
Jerry Coffin

11
คุณจะประหลาดใจกับความแตกต่างที่รวดเร็วกัดคุณ (และยาก ) SomeObject a = previousObject;ทำสิ่งที่แตกต่างกันมากใน Java และ C ++ ใน Java มันจะคัดลอกการอ้างอิงในขณะที่ C ++ มันจะคัดลอกวัตถุ ใน Java การแก้ไขaจะมีผลกับวัตถุก่อนหน้าด้วย ใน C ++ คุณมีวัตถุสองชิ้นแยกกัน
Clockwork-Muse

คำตอบ:


307

ไม่ได้นี่คือการเข้าใจผิดอย่างเลวร้ายและชะมัด

  • คุณสมบัติ Java ไม่ได้ดีไปกว่าคุณสมบัติ C ++ โดยเฉพาะในสุญญากาศ
  • หากโปรแกรมเมอร์ของคุณไม่รู้จักวิธีใช้คุณลักษณะฝึกอบรมหรือจ้างนักพัฒนาที่ดีกว่า การ จำกัด ผู้พัฒนาของคุณให้แย่ที่สุดในทีมของคุณคือวิธีที่ง่ายและรวดเร็วในการลดผู้พัฒนาที่ดี
  • YAGNI แก้ปัญหาจริงของคุณในวันนี้ไม่ใช่ปัญหาของอนาคต

6
มีคำถามเมื่อเร็ว ๆ นี้เกี่ยวกับนักพัฒนาตรวจสอบรหัสในภาษาที่พวกเขาไม่ได้เขียนตามปกติ ฉันคิดว่าภูมิปัญญามีผลกับที่นี่: นักพัฒนาที่ดีจะสังเกตเห็นข้อผิดพลาดพื้นฐานหลาย ๆ อย่างเกี่ยวกับภาษาใดก็ได้ แต่แต่ละภาษามีจำนวนมากที่ได้รับประโยชน์สูงสุดเมื่อนักพัฒนาในภาษาทำการตรวจสอบ สิ่งนี้จะเป็นจริงถ้า C ++ ของคุณเป็น "คุณสมบัติของ Java เท่านั้น"
corsiKa

5
+1 นอกเหนือจากจุดที่สองของคุณ OP ควรใช้เวลาในการอ่านเกี่ยวกับ "วิธีปฏิบัติที่ดีที่สุดสำหรับ C ++" เพื่อตัดสินใจว่าคุณลักษณะใดที่ควรใช้ ข้อมูลล่าสุดของฉันเกี่ยวกับ C ++ คือฟังก์ชั่นเพื่อนและการสืบทอดหลาย ๆอย่างถือว่าไม่เหมาะสม สิ่งต่าง ๆ เช่นเทมเพลตและโอเปอเรเตอร์การบรรทุกเกินพิกัดเป็นแนวทางปฏิบัติที่ดีของ IMHO หากคุณใช้อย่างชาญฉลาด
some_coder

4
@some_coder: มันเป็นเรื่องของการรู้ว่าเมื่อใดและที่ไหน เมื่อฉันทำการเขียนโปรแกรมตามนโยบายฉันจะสืบทอดจากคลาสนโยบาย (อาจเป็นหลาย ๆ คลาส) เพื่อขยายโครงสร้างของคลาสโฮสต์ของฉันกับสมาชิกที่คลาสนโยบายเหล่านั้นต้องการใช้งาน มันเป็นวิธีการทำงาน นอกจากนี้มักจะดำเนินการผ่านทางoperator<<( ostream &, T const & ) friendนั่นคือปัญหาที่มีงบผ้าห่มเกี่ยวกับสิ่งที่เป็นคุณลักษณะภาษาที่ดีและสิ่งที่ไม่ดีที่หนึ่ง: พวกเขามีคำแนะนำที่ดียกเว้นเมื่อพวกเขาไม่ได้ ...
DevSolar

142

เพียงเพราะไวยากรณ์ดูเหมือนว่าคล้ายกันบนพื้นผิวไม่ได้หมายความว่าทั้งสองภาษาเข้ากันได้

1, 4 และ 5 เป็นคำถามเดียวกันจริง ๆ :

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

ถ้าผู้นำของคุณตัดสินใจว่าคุณกำลังจะพอร์ตไปยัง C # แทนที่จะเป็น Java ไม่เพียง แต่รองรับ C # เท่านั้นที่จะสามารถเอาชนะโอเปอเรเตอร์ได้ แต่ยังเป็นค่าเริ่มต้นด้วย - หากคุณต้องการให้ผู้ใช้ใช้งานobj.Equals(obj2)แทนเช่นobj == obj2ผู้คนจะทำผิดพลาดอยู่ตลอดเวลา แม้ว่าคุณจะรักษาคุณลักษณะทั่วไปของทั้งสองภาษาเท่านั้น แต่ก็มีความคาดหวังที่แตกต่างกันวัฒนธรรมที่แตกต่างกัน ถ้าคุณทำอะไรบางอย่างif (myField == null)ใน C ++ ผู้คนจะเห็นคุณเป็นสามเณรทันที หากคุณใช้if (null == myField)ใน C # ผู้คนจะเห็นว่าคุณไม่ใช่เจ้าของภาษา C # จริงๆ - เหตุผลที่นักพัฒนา C เรียนรู้ที่จะใช้ตัวแปร "พลิก" ที่ไม่มีอยู่ใน C # อีกต่อไป

การใช้ตรรกะของคุณเราควรติดอยู่กับรหัสเครื่องหรือแอสเซมบลีหรือ COBOL เพราะเหตุใดจึงเปลี่ยนเป็น Pascal เมื่อมันเพิ่งเพิ่มคุณสมบัติใหม่ที่โปรแกรมเมอร์ของคุณจะต้องเรียนรู้? ทำไมเราถึงใช้ SQL เช่นเมื่อไม่มีลูป ? ทำไมเราจะใช้อย่างอื่นนอกเหนือจาก SQL เมื่อ SQL ไม่มีลูปและXทำ

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

การแปลงรหัส C ++ เหมือน Java จะเป็นข้อผิดพลาดอย่างมากที่เกิดขึ้นไม่ว่าคุณจะทำอะไร มีความแตกต่างมากเกินไป หากคุณสนใจที่จะเขียนแอปพลิเคชันของคุณในภาษาอื่นลองคิดหาวิธีที่เหมาะสมในการทำให้เป็นโมดูลทุกอย่างเพื่อให้คุณสามารถเปลี่ยนชิ้นส่วนได้โดยไม่ทำให้ชิ้นส่วนทั้งหมดพัง แต่ท้ายที่สุด YAGNI - ไม่ว่าคุณจะทำอะไรจะมีค่าใช้จ่ายที่สำคัญในการทำให้โค้ดของคุณ "พร้อมที่จะแปลงเป็น Java" ถึงเวลาที่น่าจะดีกว่าที่จะใช้เพิ่มหรือปรับปรุงคุณสมบัติของคุณ

เราใช้ภาษาที่แตกต่างกันเพราะพวกเขาให้เครื่องมือที่แตกต่างกันในการแก้ปัญหา หากคุณต้องการไฟล์โปรแกรมที่ใช้งานได้ทุกที่ให้ไปกับ Java หากคุณต้องการรหัสที่คอมไพล์ "ทุกที่" C ++ จะทำงานได้ดี หากคุณต้องการรหัสที่เข้าใจง่ายและแยกวิเคราะห์ให้ใช้ LISP หรืออะไรก็ได้ แต่ฉันสามารถบอกคุณได้สิ่งหนึ่ง - การเขียนโค้ดในภาษาหนึ่งราวกับว่าคุณกำลังเขียนอยู่ในอีกภาษาหนึ่งเป็นความผิดพลาดเสมอและคุณจะประสบ ไม่ต้องพูดถึงว่าเมื่อคุณจ้างผู้ชาย C ++ จริง ๆ เขาจะรันอันดับที่สองเขาเห็นว่ารหัส "ใช้งานร่วมกับ Java-ish" ได้ และ ... คนที่แต่งตัวประหลาด Java จะทำเช่นเดียวกัน คุณก็รู้แม้กระทั่ง "รู้" ทั้ง C ++ และ Java ฉันจะทำงานเหมือนนรก :)

ที่จริงฉันต้องทำงานกับโค้ด C ธรรมดา (ธรรมดา) ที่เขียนโดยนักพัฒนา Pascal ที่ดูเหมือนจะคิดว่าคุณทำ เขาใช้#defines เพื่อนิยาม C เพื่อค้นหาและรู้สึกเหมือน Pascal อีกครั้งพร้อมกับสิ่งต่างๆเช่น "BEGIN แปลเป็น {" ผลลัพธ์นั้นค่อนข้างคาดการณ์ได้ - โค้ดที่ทั้งนักพัฒนา C และ Pascal ไม่สามารถเข้าใจได้และเต็มไปด้วยข้อบกพร่องที่เป็นผลมาจาก "abstraction" ที่รั่วไหลของ Pascal ที่อยู่ด้านบนของ C และ Pascal และ C เกือบจะเหมือนกันจากมุมมองของทุกวันนี้ แม้แต่การไปที่ C <-> C ++ ก็มีความแตกต่างกันมากมายและนั่นก็ยังคงเป็นถั่วลิสงกับ C ++ <-> Java


9
"ถ้าคุณต้องการรหัสที่เข้าใจง่ายและแยกวิเคราะห์ใช้ LISP หรืออะไรก็ได้" ฉันจะไม่เห็นด้วยกับที่ เสียงกระเพื่อมเป็นเรื่องง่ายที่จะแยกวิเคราะห์ แต่เพราะสิ่งนี้ - เพราะมันถูกสร้างขึ้นในช่วงเวลาที่ความรู้ในการแยกวิเคราะห์และหลักการที่อยู่เบื้องหลังการสร้างพวกเขาได้อย่างมีประสิทธิภาพยังอยู่ในวัยเด็กของพวกเขาดังนั้นพวกเขาจึงเขวี้ยง ซึ่งอาจเป็นไปได้ - คุณไม่ได้รับประโยชน์จากวากยสัมพันธ์มากมายของภาษาสมัยใหม่ ดังนั้นจึงง่ายต่อการแยกวิเคราะห์ แต่ไม่เข้าใจง่าย มีเหตุผลที่ผู้คนเรียกกันว่า "หลงในวงเล็บที่ฟุ่มเฟือย"
Mason Wheeler

9
@MasonWheeler นั่นเป็นเรื่องของรสนิยม - โปรแกรมเมอร์ C เรียกมันว่าไม่ใช่ LISPers: P นับวงเล็บ - มีมากพอ ๆ กับในโปรแกรม C ++ ทั่วไปของคุณ ความแตกต่างที่แท้จริงคือตำแหน่งของพวกเขา ( myFunc()เทียบกับ(myFunc)) และนั่นเป็นเหตุผลที่ดีมาก ภาษาที่ใช้ LISP ยังคงเป็นที่นิยมมากโดยเฉพาะอย่างยิ่งกับคนคณิตศาสตร์ / ฟิสิกส์ สิ่งสำคัญคือภาษา LISPy นั้นไม่คุ้นเคยกับโปรแกรมเมอร์สไตล์ C สมัยใหม่มากนัก แต่นั่นก็เป็นเหตุผลที่ไม่สนใจเลย Scheme, Clojure และภาษาที่เป็นพื้นฐานของ ML (OCaml, F # ... ) นั้นมีความชัดเจนมาก
Luaan

4
@ Luaan ฉันสามารถบอกคุณได้อย่างแน่นอนว่า LISP ไม่เป็นที่นิยมในสาขาฟิสิกส์ ภาษาหลักสองภาษาในฟิลด์คือ FORTRAN และ C ++ FORTRAN นั้น 'ได้รับความนิยม' เพราะมีการเขียนรหัสเก่าจำนวนมาก แต่โปรแกรมใหม่เกือบทั้งหมดเขียนด้วยภาษา C ++ ในฐานะนักฟิสิกส์วิจัยฉันไม่เคยพบหรือเคยได้ยินโปรแกรม LISP ไม่ได้บอกว่าพวกเขาไม่ได้อยู่ แต่ภาษาที่แน่นอนไม่เป็นที่นิยม
James Matta

4
@Luaan เราอาจหรือไม่ต้องการนักพัฒนาซอฟต์แวร์เพิ่มเติม แน่นอนว่าเราไม่ต้องการผู้จบการศึกษาจาก CS เพิ่มเติม นั่นคือการพูดว่า "เราต้องการวิศวกรโครงสร้างมากขึ้นดังนั้นเราจึงต้องการบัณฑิตฟิสิกส์เชิงทฤษฎีมากกว่านี้"
เส้นทาง Miles Rout

4
@ user1717828 มันเพื่อหลีกเลี่ยงผลกระทบที่น่ารื่นรมย์ของ mistyping if (myField == null)เป็นif (myField = null)ซึ่งจะรวบรวมเพียงแค่ปรับ C / C ++ แต่อาจจะไม่ได้ทำในสิ่งที่คุณต้องการ ในทางกลับกันif (null = myField)จะโยนข้อผิดพลาดเนื่องจากคุณไม่สามารถกำหนดให้คงที่
Wlerin

94

ฉันจะตอบคำถามของคุณตามลำดับ

  1. หาก Java ไม่มีคุณสมบัติที่ C ++ แสดงว่าคุณสมบัตินั้นไม่ดีดังนั้นเราจึงควรป้องกันไม่ให้ใช้งาน

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

  1. รหัส C ++ พร้อมคุณสมบัติเฉพาะ C ++ (เช่น: ฟังก์ชั่นเพื่อนหลายมรดก) สามารถดูแลรักษาหรือตรวจสอบโดยโปรแกรมเมอร์ C ++ เท่านั้น แต่ถ้าเราเขียน C ++ เช่น Java (โดยไม่มีคุณสมบัติเฉพาะภาษา C ++) โค้ดนั้นสามารถรักษาหรือตรวจสอบได้โดยทั้งสอง โปรแกรมเมอร์ C ++ และ Java

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

  1. คุณอาจถูกขอให้แปลงรหัสเป็น Java ในบางวัน

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

ตอนนี้เมื่อคุณต้องการเปลี่ยนภาษาเพียงแค่เขียนโค้ดที่ห่อสตริง perl ใหม่

  1. รหัสที่ไม่มีคุณสมบัติเฉพาะ C ++ มักจะสามารถบำรุงรักษาได้มากกว่า

มันเป็นความจริงรหัสที่ใช้คุณสมบัติน้อยกว่าง่ายต่อการบำรุงรักษา และในขณะที่ทุกภาษาเทียบเท่ากับทัวริงเครื่องและทัวริงเครื่องมีคุณสมบัติที่น้อยที่สุดของภาษาการเขียนโปรแกรมใด ๆ มีล่าม perl ข้างต้นใช้จริงทัวริงเครื่อง (เทปและทั้งหมด) ที่แก้ปัญหาของคุณ

  1. คุณลักษณะเฉพาะภาษา C ++ ทุกตัว (เช่น: การสืบทอดหลายอย่าง) ควรมีทางเลือกที่จะนำไปใช้ใน Java หากไม่เป็นเช่นนั้นหมายความว่ารูปแบบการออกแบบหรือสถาปัตยกรรมรหัสเป็นปัญหา

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


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

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

คุณสามารถทำสิ่งที่น่ากลัวกับการบรรทุกเกินพิกัด; แต่ไม่มีภาษาใดสามารถป้องกันโค้ดที่น่ากลัวจากการเขียนในภาษาเว้นแต่ว่าจะหยุดโค้ดทั้งหมดจากการเขียนในภาษา

และคุณยังสามารถทำสิ่งที่สง่างามด้วยการใช้งานเกินพิกัด สิ่งที่ง่ายเช่นจำนวนเชิงซ้อนหรือคลาสเมทริกซ์ที่ทำงานเหมือนจำนวนเชิงซ้อนหรือเมทริกซ์

ข้อควรระวังเกี่ยวกับการใช้คุณสมบัติ C ++ ที่ไม่มีใน Java ควรดูด้วยความระมัดระวัง เพียงเพราะนักพัฒนาชุดปัจจุบันของคุณที่ระดับทักษะปัจจุบันไม่เข้าใจคุณลักษณะไม่ได้หมายความว่าไม่ควรใช้งาน ในเวลาเดียวกันเพียงเพราะคุณสามารถใช้คุณสมบัติไม่ได้หมายความว่าคุณควร อย่างไรก็ตามในร้านค้า Java-heavy อัตราต่อรองที่มีความต้านทานจะแข็งแกร่งกว่าที่ควรจะเป็นกับคุณสมบัติที่ไม่ใช่ Java-esque

การแปลงรหัสระหว่างภาษาทำได้ดีที่สุดด้วยการเขียนซ้ำไม่ว่าพวกเขาจะมีโครงสร้างคล้ายกันอย่างไร ความพยายามใด ๆ ในการทำเช่นนี้โดยไม่ต้องมีการเขียนใหม่จะล้มเหลวอย่างน่าสังเวช

คุณลักษณะเฉพาะของ C ++ หลายอย่างเป็นสิ่งมหัศจรรย์สำหรับการบำรุงรักษา การลบประเภท (เช่นstd::function) ช่วยให้คุณแยกลำดับชั้นได้ซึ่งจะลดการพึ่งพา พอยน์เตอร์ที่ชาญฉลาดและอายุการใช้งานที่กำหนดและ RAII ลดความประหลาดใจในการใช้งานและย้ายแหล่งข้อมูลออกไปให้พ้นทาง การตรวจสอบประเภทคงที่หนักหมายความว่ารหัสไม่สามารถคอมไพล์แทนที่จะล้มเหลวในการทำงาน มิกซ์อินลดการทำซ้ำรหัส ADL อนุญาตให้ส่วนต่อขยายที่แยกได้เป็นอิสระระหว่างส่วนลำดับชั้นของประเภท แลมบ์ดาให้คุณเขียนโค้ดถัดจากที่ใช้ การส่งต่อและการย้ายลดการทำสำเนาและทำให้การเขียนโปรแกรมลักษณะการทำงาน (ไม่มีผลข้างเคียง) มีประสิทธิภาพ ตัวดำเนินการมากเกินไปลดเสียงรบกวนของเส้นและทำให้โค้ดดูเหมือนคณิตศาสตร์ที่กำลังสร้างแบบจำลอง

ระวังหลุมทัวริง คุณสามารถดำเนินการทุกอย่างในภาษาใด ๆ (รวมทั้งเครื่องทัวริงดิบกับเทป) แต่ไม่ได้หมายความว่าคุณควร การเลียนแบบคุณลักษณะ C ++ โดยใช้โครงสร้าง Java-esque ใน C ++ เป็นแนวคิดที่น่ากลัว มันจะส่งผลให้รหัสที่ไม่มีใครสามารถอ่านหรือเข้าใจได้

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

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


1
-1 ยืดยาวและไม่ชัดเจน
djechlin

4
-1 อาร์กิวเมนต์, อาร์กิวเมนต์ฟางชาย
949300

28
+1, โครงสร้างที่เหมาะสมของคำถามที่ถามและฉันหัวเราะ :)
แมว

11
+1 เฮฮา แต่เก็บประเด็นไว้ ชัดเจนมากสำหรับคนที่อ่านมัน
Luis Masuelli

14
"การเขียนโปรแกรมในจุดตัดของ C ++ และ Java ส่งผลให้เกิดโค้ดซึ่งทำให้ข้อดีของทั้งสองภาษาหมดไป" แทงใจดำ! +1
Ajedi32

56

ฉันแค่ตอบเหตุผลของคุณ:

  1. ฉันไม่เข้าใจว่าคุณสรุปได้อย่างไร ภาษาที่ต่างกันมีคุณสมบัติที่แตกต่างกัน ขึ้นอยู่กับขอบเขตสถาปัตยกรรมของภาษาบางครั้งการตั้งค่าของผู้สร้างและเหตุผลอื่น ๆ อีกมากมาย คุณลักษณะบางอย่างของภาษาอาจไม่ดี แต่ความเห็นโดยทั่วไปของคุณนั้นผิด IMHO
  2. การเขียน C ++ เหมือนกับ Java อาจทำให้โค้ดแย่ลง เช่นทุกวันนี้ด้วย C ++ 11 ฉันหลีกเลี่ยงการใช้ใหม่ / ลบ แต่ใช้พอยน์เตอร์ที่ใช้ร่วมกัน ในสถานการณ์ของคุณฉันจะพึ่งใหม่ / ลบ หากโปรแกรมเมอร์ของคุณเข้าใจเฉพาะ Java ให้ฝึกฝนหรือจ้างคนที่ดีกว่า
  3. นั่นเป็นไปได้ไหมที่จะเกิดขึ้น? ทำไมคุณไม่เขียนเป็นภาษาจาวาในตอนแรก ฉันคิดว่าโปรแกรมการเขียนใหม่ตั้งแต่เริ่มต้นในภาษาใหม่เป็นความคิดที่ไม่ดีและคุณจะต้องมีเหตุผลที่ดีสำหรับความเสี่ยงดังกล่าว
  4. นี่เป็นเพียงข้อสมมติ
  5. ขึ้นอยู่กับ IMHO สูงในสถานการณ์ของคุณหรือกรณีการใช้งาน

27
และ Java-โปรแกรมเมอร์ไม่ใช้deleteทั้งสองอย่าง
Paŭlo Ebermann

8
ฉันได้มีการแก้ไขปัญหาการรั่วไหลของหน่วยความจำที่เกิดจากการเขียนโปรแกรม Java deleteไม่ทราบเกี่ยวกับ จากสิ่งที่ฉันจำได้ในกรณีอย่างน้อยหนึ่งกรณีการจัดสรรแบบไดนามิก ( new) ก็ไม่จำเป็นเช่นกัน
Ethan Kaminski

16
@EthanKaminski ใช่นั่นเป็นวิธีที่คุณสามารถเห็นมือใหม่ C ++ ได้อย่างง่ายดายโดยเฉพาะคนที่มาจากพื้นหลัง Java หรือคล้ายกัน หยุดใช้ของใหม่สำหรับทุกอย่างเถอะ!
Luaan

1
@ PaŭloEbermannใช่แย่ยิ่งกว่า
Simon

1
"ในสถานการณ์ของคุณฉันจะต้องใช้เฉพาะในใหม่ / ลบ" - ตลกผมจะคิดว่า "Java (เหมือน) -features เท่านั้น" C ++ make_sharedสำนวนจะใช้เฉพาะ
Kyle Strand

26

Java มีคุณสมบัติที่ C ++ ไม่เช่นตัวรวบรวมขยะในตัวที่รวดเร็วและเชื่อถือได้ลำดับชั้นของวัตถุรูทเดียวและวิปัสสนาอันทรงพลัง

คุณสมบัติอื่น ๆ ของ Java ได้รับการออกแบบให้ทำงานร่วมกับคุณสมบัติพิเศษเฉพาะของ Java และคุณสมบัติ C ++ ของ Java ที่เป็นไปได้หลายประการนั้นเป็นไปได้เนื่องจากคุณลักษณะใหม่ประกอบไปด้วยสิ่งที่ขาดไป ตัวอย่างเช่น Java ไม่มีวัตถุที่จัดสรรสแต็กด้วย destructic destructors แต่ในที่สุดก็มีการบล็อก (และลองกับทรัพยากรตั้งแต่ Java 7) และตัวรวบรวมขยะเพื่อชดเชยการขาดนี้

C ++ ไม่มีการบล็อกหรือการรวบรวมขยะในที่สุด หากคุณไม่ได้ใช้ destructors เนื่องจากไม่มีอยู่ใน Java (ฉันไม่นับ finalizers) คุณอยู่ในระดับ C ของการจัดการทรัพยากร (เช่นคู่มือทั้งหมด) ยกเว้นว่าคุณไม่สามารถจัดกลุ่มการล้างข้อมูลของคุณได้ เป็นบล็อกการล้างข้อมูลที่คุณข้ามไปเนื่องจาก Java ไม่มีข้ามไปเช่นกัน คุณคิดว่ามันช่วยปรับปรุงการบำรุงรักษาหรือไม่?

Java มีลำดับชั้นของวัตถุที่ครอบคลุมซึ่งแต่ละคลาสนั้นมาจาก Object ในที่สุดและชนิดดั้งเดิมบางอย่างสามารถถูกใส่เข้าไปในคลาสดังกล่าวได้โดยอัตโนมัติ สิ่งนี้ช่วยให้การเขียนคอนเทนเนอร์ของวัตถุหนึ่งครั้งเพื่อเก็บพอยน์เตอร์ไปยังวัตถุ Java 5 แนะนำ generics ซึ่งกำจัด casts ภาชนะบรรจุที่จำเป็น แต่ยังคงรวบรวมลงในรหัสเดียวกันสวยมาก

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

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

ไม่ได้หมายความว่าคุณจะต้องไม่ จำกัด คุณสมบัติที่อนุญาตของ C ++ C ++ เป็นภาษาที่โตแล้วในอดีตที่เน้นการเปิดใช้งานโปรแกรมเมอร์ให้ทำสิ่งที่เขาต้องการในด้านความปลอดภัยและความสะดวกในการใช้งานและคุณสมบัติบางอย่างในความยืดหยุ่นทั้งหมดนั้นไม่จำเป็นต้องมีเพื่อสร้างโปรแกรมที่ดี มีมาตรฐานการเข้ารหัสมากมายที่ จำกัด การใช้คุณสมบัติบางอย่าง ตัวอย่างเช่นคำแนะนำของ Google ส่วนใหญ่ห้ามมิให้มีการสืบทอดหลายแบบเทมเพลตที่ซับซ้อนและข้อยกเว้น (แม้ว่าข้อสุดท้ายจะเป็นเพราะเหตุผลทางประวัติศาสตร์) แต่ไม่มีคุณสมบัติที่ห้าม "เพราะ Java ไม่มี"; คุณสมบัตินี้ได้รับการพิจารณาภายในกรอบของ C ++ เพียงอย่างเดียว


27
ทหารผ่านศึก C ++ รุ่นเก๋ามักจะปฏิเสธแนวทางการเข้ารหัสของ Google Modern C ++ นั้นดีกว่าเพราะมันใช้คุณสมบัติเหล่านั้น ใช่มันทำให้แตกต่างมากขึ้น
Jan Hudec

17
โปรดทราบว่า C ++ ไม่มีการบล็อกในที่สุด แต่จะมี RAII ซึ่งดีกว่ามากสำหรับกรณีส่วนใหญ่ และแตกต่างกันอีกครั้ง
Jan Hudec

7
Java's Objectค่อนข้างเป็นvoid*ของใช้ส่วนใหญ่ - ยังไงก็เถอะ
เควนติ

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

2
ฉันจะ upvote คำตอบนี้อยู่ในการติดตามที่ถูกต้อง ("ไม่ทำมัน") แต่ฉันไม่สามารถยืนหลักฐานพื้นฐานที่ Java เป็นอย่างใด "ขั้นสูง" กว่า C ++ C ++ ไม่จำเป็นต้องมีตัวรวบรวมขยะหรือลำดับชั้นของวัตถุรูทเดียวเช่นเดียวกับที่ Java ไม่ต้องการ ... เอ่อ ... ขอโทษฉันไม่รู้ว่าจะจบประโยคได้อย่างไรเพราะฉันคิดถึง destructic destructor ใน Java และfinallyไม่ใช่สิ่งทดแทนสำหรับพวกเขา สองภาษานั้นแตกต่างกันโดยพื้นฐาน
DevSolar

25

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

ความแตกต่างระหว่าง Java และ C ++ ทำงานได้ลึกกว่ารายละเอียดที่คุณมุ่งเน้นมาก

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

C ++ ไม่แยกแนวคิดทั้งสองอย่างนั้น อะนาล็อก C ++ ที่ใกล้เคียงที่สุดนำเสนอการใช้งานอินเทอร์เฟซใน Java กำลังสืบทอดจากคลาสอื่น ดังนั้นเพื่อให้การจัดตำแหน่งทั้งสองสอดคล้องกันอย่างสมเหตุสมผลคุณอาจจำเป็นต้องใช้การสืบทอดหลายรายการใน C ++ แต่คุณต้องการ จำกัด คลาสพื้นฐานเหล่านั้นบางส่วนด้วยวิธีเดียวกันกับ Java จำกัด อินเทอร์เฟซเปรียบเทียบกับคลาส (เช่นโดยพื้นฐานแล้ว มันระบุฟังก์ชั่นลายเซ็น แต่อย่างน้อยส่วนใหญ่ไม่ใช้งาน)

นั่นเป็นเพียงการเกาพื้นผิวของความแตกต่างที่แท้จริงระหว่างสองอย่างนั้น ในความเป็นจริงที่โค้ด Java มีแนวโน้มที่จะกำหนดอินเตอร์เฟสและคลาสที่ใช้อินเตอร์เฟสเหล่านั้นรหัส C ++ นั้นมีแนวโน้มที่จะกำหนดเทมเพลตบางตัวที่จะทำงานกับคลาสใด ๆที่ตรงกับความต้องการของมันมากขึ้น(s) มันระบุ)

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

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


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

สมมุติว่าคุณพูดว่า "อาจต้องการ" คุณหมายถึง: "อาจไม่ต้องการ"? ถ้าอย่างนั้นฉันก็มักจะเห็นด้วย
Jerry Coffin

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

4
@supercat: OTOH เนื่องจากมีจำนวนแพลตฟอร์มที่รองรับ Java แต่ไม่ใช่ C ++ นี่ทำให้ฉันเกือบจะเป็นทางออกในการค้นหาปัญหา
Jerry Coffin

สำหรับชั่วขณะสนับสนุนเบราว์เซอร์สำหรับ Java applets ดีกว่าสำหรับ C ++ applets การสนับสนุนเบราว์เซอร์สำหรับ JavsScript (ไม่มีความสัมพันธ์กับ Java) แต่ได้ปรับปรุงให้ดีพอที่จะใช้งานได้จริงจากทั้งสองอย่าง
supercat

11

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

ปีที่แล้วฉันเห็นโปรแกรม C ที่ไม่มีการเยื้องและทุกคำสั่งเริ่มต้นในคอลัมน์ 7 เพราะผู้เขียนรหัสเป็นโปรแกรมเมอร์ Fortran ที่ใช้ซี C. โปรแกรมเมอร์อื่น ๆ ของ Fortran กังวลเรื่องสิ่งใหม่ที่เรียกว่าพอยน์เตอร์ ฉันไม่มีหัวใจที่จะพูดถึงพอยน์เตอร์ต่อพอยน์เตอร์ฉันคิดว่าพวกเขาจะหมดสติไปทันที

ลองนึกภาพคนว่าจ้างให้รักษารหัสนี้ในอนาคต หากเป็นรหัส C ++ ที่ดีคุณจะสามารถจ้างนักพัฒนา C ++ ที่มีความสามารถและพวกเขาควรจะสามารถหาวิธีแก้ไขได้ หากเป็น "Java ใน C ++" ดังนั้นนักพัฒนา C ++ และ Java จะไม่เข้าใจรหัสได้ง่าย


7

เหตุผลทั้งหมดของคุณสามารถพิสูจน์ได้:

หาก Java ไม่มีคุณสมบัติที่ C ++ แสดงว่าคุณสมบัตินั้นไม่ดีดังนั้นเราจึงควรป้องกันไม่ให้ใช้งาน

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

รหัส C ++ พร้อมคุณสมบัติเฉพาะ C ++ (เช่น: ฟังก์ชั่นเพื่อนหลายมรดก) สามารถดูแลรักษาหรือตรวจสอบโดยโปรแกรมเมอร์ C ++ เท่านั้น แต่ถ้าเราเขียน C ++ เช่น Java (โดยไม่มีคุณสมบัติเฉพาะภาษา C ++) โค้ดนั้นสามารถรักษาหรือตรวจสอบได้โดยทั้งสอง โปรแกรมเมอร์ C ++ และ Java

เป็นไปได้ไหม ลองดูรหัส C ++ ที่ง่ายที่สุด:

int len = mystring->size();

โอ๊ะโอไม่ได้ใช้คุณสมบัติ "ภาษาเฉพาะ" แต่ Java devs ยังคงไม่มีใครเปลี่ยนแปลง! เพราะใน Java คุณต้องพูดถึง "." ในขณะที่นี่คือ "->

คุณอาจถูกขอให้แปลงรหัสเป็น Java ในบางวัน

หรือ C # หรือ Haskell หรือ Python หรือทับทิม หรือ COBOL (ใช่คุณทำได้!) คุณจะบอกอนาคตได้อย่างไร

รหัสที่ไม่มีคุณสมบัติเฉพาะ C ++ มักจะสามารถบำรุงรักษาได้มากกว่า

ตรงข้ามอย่างแน่นอน ทุกคุณสมบัติถูกนำมาใช้เพื่อให้การเขียนโปรแกรมง่ายขึ้นดังนั้นบำรุงรักษาได้มากขึ้น เช่น: ใช้โปรแกรมปฏิบัติการบนลอย ตอนนี้อัปเกรดเป็นหมายเลขที่ซับซ้อน ผู้ประกอบการบรรทุกเกินพิกัดเพื่อช่วยเหลือ!

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

แต่ Java มีมรดกหลายอย่าง! มันเรียกว่า "อินเตอร์เฟซ" การดำเนินงาน Java Objectเป็นวิธีแก้ปัญหาที่มีปัญหาที่จะหลีกเลี่ยงเพชรหวั่นเกิดจากมีทุกอย่างที่เป็นผลมาจาก มันทำโดยการแนะนำซึ่งวัตถุประสงค์เพียงอย่างเดียวคือการเป็นสิ่งที่ไม่ได้เป็นผลมาจากinterface ObjectC ++ ไม่เคยมีปัญหานี้ - ไม่มีฐานบังคับทั่วไปดังนั้นทุกชั้นสามารถทำงานเป็นอินเทอร์เฟซที่ไม่มีเพชรที่น่ากลัว

หมายเหตุด้านข้าง: Java เพิ่งเปิดตัว ... วิธีการที่เป็นรูปธรรมในการเชื่อมต่อ เพิ่มคุณสมบัติ C ++ เสมอเพื่อแก้ปัญหาที่ไม่เคยมี

คุณได้กล่าวถึง "สิ่งที่ C ++ มีเพียงไม่กี่ตัวเท่านั้น แต่ Java ไม่ได้" หนึ่งในความแตกต่างที่ใหญ่ที่สุดระหว่าง C ++ และ Java คือการควบคุมเลย์เอาต์ของหน่วยความจำ คุณสามารถสร้างอาร์เรย์ของตัวชี้ไปยังวัตถุ (เช่นเดียวกับใน Java) หรือคุณสามารถสร้างบล็อกหน่วยความจำต่อเนื่อง ตอนนี้ถ้าฉันต้องกังวลเกี่ยวกับคุณลักษณะ C ++ ที่อาจทำให้เข้าใจผิด Java devs บางสิ่งที่ซ่อนเร้นและบอบบางตามที่สิ่งนี้จะจัดอันดับในรายการของฉันสูงกว่าที่ชัดเจนและเป็นที่รู้จักในสิ่งแรกเห็นเช่นมรดกหลายอย่าง

บรรทัดล่าง: รหัสที่สะอาดคือรหัสที่สะอาด Java หรือ C ++ - ต่างกัน เพียงแค่ทำให้มันง่าย ภาวะแทรกซ้อนที่ไม่จำเป็นเป็นสาเหตุหลักของรหัสที่ไม่ดี


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

@supercat ฉันไม่เข้าใจว่าทำไมคุณถึงพูดที่นี่ คำถามไม่ได้เกี่ยวกับคุณสมบัติของ Java ที่ไม่สามารถทำซ้ำได้ใน C ++ แต่เกี่ยวกับคุณสมบัติ C ++ ที่ Java ถูกทิ้ง
Agent_L

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

6

ไม่มีคุณควรทั่วไปไม่เขียน c ++ เหมือนมันเป็น Java และคุณควรแน่นอนไม่ละเว้น c ++ คุณสมบัติภาษาที่ไม่อยู่ในชวา

ประการหนึ่งคือ Java เก็บขยะและดังนั้นจึงไม่มีคำหลัก "ลบ" C ++ ที่เทียบเท่ากัน ตกลงดังนั้นคุณใช้โปรแกรมโดยไม่ลบเพราะกฎของคุณไม่อนุญาต

ขอแสดงความยินดีขณะนี้คุณมีหน่วยความจำรั่ว;) นั่นไม่ใช่ทฤษฎีเช่นกัน - ฉันเคยเห็นสถานการณ์ที่แน่นอนนี้เกิดขึ้นในเกมโอเพ่นซอร์ส

ในทำนองเดียวกัน Java ไม่ได้มีอะไรมากเช่น C ++ ชี้ซึ่งกฎออกจำนวนมากของการทำงานร่วมกันประชุมโทร

มีคุณสมบัติของ C ++ ที่คุณควรหลีกเลี่ยง (ดูด้านล่าง) แต่ "ไม่อยู่ใน Java" ไม่ใช่การทดสอบสารสีน้ำเงินที่ดี


แนวทางที่ดีกว่าจะเป็นดังนี้:

  1. เขียนรหัสที่เหมาะสมกับภาษาสภาพแวดล้อมและเครื่องมือของคุณ
  2. เขียนโค้ดที่ทีมของคุณสามารถเข้าใจได้
  3. ตรวจสอบให้แน่ใจว่าทีมของคุณมีความสามารถในโดเมนที่กำหนด

รายการ (3) หมายความว่าคุณไม่ควรมีรหัสโปรแกรมเมอร์ Java ใน C ++ โดยไม่ต้องฝึกอบรมใน C ++ มีความแตกต่างที่ลึกซึ้ง แต่สำคัญมากซึ่งพวกเขาอาจไม่ได้เรียนรู้ว่าพวกเขากำลังพยายามที่จะปฏิบัติกับมันเหมือนภาษาแปลก ๆ ของ Java

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


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


6

มีคำตอบอื่น ๆ อยู่บ้าง แต่ฉันต้องการที่จะให้คำตอบที่สมบูรณ์ยิ่งขึ้นโดยตอบคำถามและข้อความของคุณทีละรายการ


หาก Java ไม่มีคุณสมบัติที่ C ++ แสดงว่าคุณสมบัตินั้นไม่ดีดังนั้นเราจึงควรป้องกันไม่ให้ใช้งาน

นี่เป็นคำตอบที่ค่อนข้างดี: Java ไม่ได้เป็น "ส่วนที่ดี" ของ C ++ และไม่มีเหตุผลที่จะคิดเช่นนั้น

โดยเฉพาะอย่างยิ่งถึงแม้ว่าข้อดีของแต่ละคุณสมบัติของ C ++ นั้นจะเป็นที่ถกเถียงกันอยู่ แต่คุณสมบัติหลายอย่างของ C ++ 11 / C ++ 14 ที่ไม่ได้เป็นส่วนหนึ่งของ Java นั้นไม่จำเป็นต้องถูกแยกออกเพราะนักออกแบบ Java คิดว่าพวกเขาคิดไม่ดี เป็นกรณีตัวอย่างจนถึงรุ่น 8, Java ไม่มี lambdas แต่ได้รับการแนะนำให้รู้จักกับ C ++ ในมาตรฐาน C ++ 11 ก่อนหน้า Java 8 ข้อสันนิษฐานของคุณว่าคุณสมบัติ C ++ ที่หายไปจาก Java นั้นขาดหายไปจากการออกแบบเพราะพวกเขา "ไม่ดี" จะบอกเป็นนัย ๆ ว่า lambdas ในฐานะที่เป็นภาษานั้น "ไม่ดี" (สำหรับ LISPers ทุกหนทุกแห่ง อาจจะน่ากลัวพอที่จะได้ยินว่าคุณชอบ Java จริงๆ) แต่ตอนนี้นักออกแบบ Java ได้ใส่ Stamp of Approval (TM) ลงในลูกแกะดังนั้นพวกเขาจึงเป็นสิ่งที่ดี

การขุดลึกลงไปอีกเล็กน้อยแม้ใน Java 8 lambdas-as-closures นั้นไม่ยืดหยุ่นเท่ากับ lambdas ของ C ++ 14 แต่สิ่งนี้อาจเกิดจากข้อ จำกัด ทางสถาปัตยกรรมของ JVMมากกว่าการตัดสินใจอย่างมีสติว่าวิธียืดหยุ่นมากกว่านั้นไม่ดีจาก มุมมองการออกแบบภาษา


รหัส C ++ พร้อมคุณสมบัติเฉพาะ C ++ (เช่น: ฟังก์ชั่นเพื่อนหลายมรดก) สามารถดูแลรักษาหรือตรวจสอบโดยโปรแกรมเมอร์ C ++ เท่านั้น แต่ถ้าเราเขียน C ++ เช่น Java (โดยไม่มีคุณสมบัติเฉพาะภาษา C ++) โค้ดนั้นสามารถรักษาหรือตรวจสอบได้โดยทั้งสอง โปรแกรมเมอร์ C ++ และ Java

นี่คือสิ่งสำคัญที่ฉันต้องการตอบสนอง

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

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

ก่อนอื่นลองคิดดูว่ามันจะทำให้ C ++ มีลักษณะอย่างไร "Java ในกรณีง่าย ๆ คุณสามารถใช้newเพื่อยกตัวอย่างวัตถุได้เหมือนกับใน Java:

Foo foo = new Foo();

แต่ออบเจ็กต์นั้นใช้วิธีนี้->แทนการใช้.เมธอด call ดังนั้นหากคุณต้องการให้เมธอดcallดูเหมือน Java คุณต้องเขียนแทน:

Foo& foo = *new Foo();

แต่นี่ไม่ใช่เรื่องจริง โดยเฉพาะอย่างยิ่งหน่วยความจำจะต้องต่อมาจะมีการทำความสะอาดขึ้นใช้delete &fooซึ่งบางคนมีประสบการณ์ c ++ devs อาจไม่ได้ตระหนักถึงความเป็นรหัสทางกฎหมาย ทั้งสองวิธีมีตลกสัญลักษณ์ไม่ใช่ Java เหมือนโรยตลอดดังนั้นเราจึงไม่สามารถค่อนข้างทำให้ภาษา "มีลักษณะเหมือน" Java (คุณสามารถกำจัด*newโดยใช้#define New *newหรือแย่กว่า#define new *newนั้น แต่คุณแค่ขอให้เพื่อนร่วมงานของคุณเกลียดคุณ) และตามที่กล่าวไว้ข้างต้นdeleteไม่มีอยู่ใน Java ดังนั้นไม่ว่าในกรณีใด (ตามที่กล่าวไว้ในคำตอบอื่น ) คุณไม่สามารถทำให้การใช้งานวัตถุ "ดู" อย่างที่มันทำในจาวาโดยปราศจากการรั่วไหลของหน่วยความจำ

แต่ C ++ ที่ทันสมัยนั้นรวมถึงพอยน์เตอร์ที่ใช้ร่วมกันอย่างชาญฉลาดซึ่งทำหน้าที่เหมือนกับการอ้างอิงตัวแปรที่จัดการโดยหน่วยความจำของ Java ดังนั้นทุกที่ใน Java ที่คุณสามารถเขียนFoo foo = new Foo();คุณสามารถเขียนแทน:

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

ตอนนี้คุณกำลังใช้ฟีเจอร์ภาษาที่เหมือนกับ Java อยู่ใต้กระโปรงหน้ารถ แต่ทันใดนั้นคุณมีอะไรหลายอย่างที่ต้องอธิบายให้ผู้ตรวจสอบที่ไม่ใช่ C ++: สิ่งนี้คือshared_ptrอะไร อะไร "gotchas" ที่ละเอียดอ่อนของmake_sharedคืออะไร? (มันใช้การส่งต่อที่สมบูรณ์แบบซึ่งมีบางกรณีที่ล้มเหลวและสามารถนำไปสู่การเรียกใช้คอนสตรัคเตอร์ "ผิด") ทำไมต้องทำการเรียกเมธอดด้วย->แต่การใช้.กับเมธอดบางตัวอนุญาตโดยคอมไพเลอร์? ( shared_ptrมีวิธีการของตัวเอง.) หากวิธีการที่Foo::reset(void)มีอยู่นักพัฒนาไม่ระวังอาจจะพยายามที่จะเรียกมันด้วยfoo.reset()ซึ่ง (ถ้ามีเพียงหนึ่งชี้ตัวชี้ที่ใช้ร่วมกันเช่นว่าFooเมื่อมีการโทรเกิดขึ้น) จะลบหน่วยความจำพื้นฐานและลบล้างfooและ นักพัฒนา Java ไม่น่าจะพบปัญหานี้

นอกจากนี้C ++มีจำนวนมากของข้อผิดพลาดที่มีเฉพาะกับภาษา. อย่างที่ฉันบอกได้ผู้พัฒนา C ++ ส่วนใหญ่เรียนรู้ที่จะจัดการกับข้อผิดพลาดเหล่านี้โดยค่อยๆพัฒนาสำนวนของตัวเองสำหรับการปฏิบัติ C + + ที่ปลอดภัยซึ่งมักจะเป็นเอกลักษณ์ของพวกเขาหรือทีมพัฒนาของพวกเขา (ดูตัวอย่างคำตอบที่มีอยู่ แนวทางปฏิบัติในการเขียนโค้ดของ Google และความคิดเห็นเกี่ยวกับเรื่องนี้ระบุว่า "ทหารผ่านศึก C ++ เก๋ามักจะปฏิเสธแนวทางการเข้ารหัสของ Google") ทุกคนอ้างว่าภาษานั้นอาจซับซ้อนเกินไปดูเหมือนว่า (อย่างน้อยประสบการณ์ของฉัน) มักจะพบกับรูปแบบของ "ดีหยุดใช้ผิดเลย" ผมทราบดีว่านี่เป็นมุมมองเชิงลบอย่างมากของ C ++ ชุมชนและมีแน่นอนพัฒนาที่มีประสบการณ์มีความเต็มใจที่จะช่วยออกภาษาเรียน แต่มีไม่ ดูเหมือนว่าจะมีการป้องกันบางอย่างเกี่ยวกับพฤติกรรมที่ไม่ได้กำหนดเช่น (ดูตัวอย่างของการสนทนาในลิงก์ 'ผิดพลาด' ของฉันด้านบน)

นักพัฒนา Java จะไม่เป็นประโยชน์ในการค้นหาและแก้ไขข้อผิดพลาดเหล่านี้ผ่านการตรวจสอบโค้ด


คุณอาจถูกขอให้แปลงรหัสเป็น Java ในบางวัน

ถูกต้องทั้งหมด - น่ายกย่องแม้ - ลองพิจารณาสิ่งที่อาจเกิดขึ้นกับรหัสของคุณในอนาคตในขณะที่คุณอยู่ในขั้นตอนการออกแบบ

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

และสองคุณพูดในภายหลัง

คุณลักษณะเฉพาะภาษา C ++ ทุกตัว (เช่น: การสืบทอดหลายอย่าง) ควรมีทางเลือกที่จะนำไปใช้ใน Java ...

สิ่งนี้จะยกเลิกจุด "แปลงเป็น Java" ของคุณ หากซอฟต์แวร์เขียนด้วย idiomatic C ++ จากนั้นแปลงเป็น idiomatic Java ก็ไม่มีเหตุผลที่จะคาดหวังว่าการแปลงนี้จะทำได้ (หรือทำได้!) โดยการใช้การแมปแบบหนึ่งต่อหนึ่งที่แม่นยำของคุณสมบัติ C ++ กับคุณสมบัติ Java


รหัสที่ไม่มีคุณสมบัติเฉพาะ C ++ มักจะสามารถบำรุงรักษาได้มากกว่า

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

... 80% ของผู้พัฒนาเข้าใจมากที่สุด 20% ของภาษา มันไม่เหมือนกันกับ 20% สำหรับคนที่แตกต่างกันดังนั้นอย่าหวังให้พวกเขาเข้าใจรหัสของกันและกัน

โปรดทราบ:หากคุณเป็นแฟน C ++ และคุณมาถึงจุดนี้ในคำตอบของฉันและรู้สึกอยากจะกระโดดลงไปที่ความคิดเห็นเพื่อยืนยันว่าผู้เขียน FQA ไม่เข้าใจจริง ๆ C ++ หรือขัดแย้งกันมากในข้อโต้แย้งของเขา โปรดทราบว่า (1) สองประโยคหลังจากที่ฉันอ้างถึงเขาฉันยอมรับว่า FQA เป็นแหล่งที่มีอคติมากและ (2) ไม่สำคัญเลยสำหรับสิ่งที่ฉันพยายามจะพูดว่าผู้เขียน FQA เข้าใจ C ++ หรือไม่ และฉันไม่ได้พยายามทุบตี C ++ และคุณควรอ่านส่วนที่เหลือของโพสต์โดยไม่คิดว่าฉันต่อต้าน C-C เพียงเพราะฉันอ้างถึง FQA จบโน้ต

ในทำนองเดียวกัน Linus Torvalds เกลียด C ++ ด้วยเหตุผลนี้ (คำเตือน: ลิงก์เกี่ยวข้องกับการสบถจำนวนมากในสไตล์ Linus ที่น่าอับอายอย่างแท้จริง)

เห็นได้ชัดว่าสิ่งเหล่านี้มีความลำเอียงอย่างมากในเรื่องนี้ แต่ผู้สนับสนุน C ++ มักบอกว่าคุณไม่ควรใช้ชุดคุณลักษณะภาษาทั้งหมด (อีกครั้งดูแนวทางการเข้ารหัสของ Google เช่นกัน Bjarne Stroustrup ผู้สร้าง C ++ ได้กล่าวต่อสาธารณชนว่า "ภายใน C ++ มีภาษาที่เล็กกว่าและสะอาดกว่าที่พยายามจะออกไป")

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

อย่างไรก็ตามการตัดสินใจว่าจะใช้ชุดย่อยใดบนพื้นฐานของภาษาที่แตกต่างกันจะไม่เหมือนกับวิธีการใช้ที่ถูกต้องเว้นแต่ว่า "ภาษาที่แตกต่าง" คือ C เนื่องจากมีเซตย่อยคล้าย C ของภาษา C ++ (Linus อ้างถึงสิ่งนี้ในการพูดจาโผงผางของเขาข้างต้นและ Scott Meyers อ้างถึงเซตย่อยนี้ว่า "sub-language") กระบวนทัศน์เวลาทำงานของ Java (เก็บขยะ, ทำงานบน VM) นั้นแตกต่างอย่างมากจาก C ++ ไม่ชัดเจนว่ามีบทเรียนใด ๆ ที่มีประโยชน์ในการวาดเกี่ยวกับการใช้งาน C ++ จากมันและดังที่ได้กล่าวไว้ข้างต้นการพยายามวาดบทเรียนเกี่ยวกับ C ++ โดยตรงจาก Java สามารถนำไปสู่

ให้ลองกำหนด "ชุดย่อยที่ยอมรับได้" ของภาษาแทนเพื่อทำความเข้าใจว่าภาษานั้นสามารถใช้สำนวนได้อย่างไร หากคุณต้องการเซตย่อยที่ค่อนข้าง จำกัด ซึ่งยังคงใช้ประโยชน์จากคุณสมบัติของ C ++ มากมายนอกเหนือจาก C ที่มีให้บริการแนวทางการเขียนโค้ด Google ดังกล่าวอาจเป็นจุดเริ่มต้นที่ดี แน่นอนคุณจะได้นักพัฒนาที่บอกว่ามี "ไม่มีเหตุผลโต้แย้ง" สำหรับข้อ จำกัด บางอย่างของ Googleแต่ถ้าคุณไม่ต้องการจ้าง Alexandrescu จากงานของเขาในภาษา D (ซึ่งตัวเองควรบอกคุณบางอย่าง) นั่นคือ อาจจะไม่เป็นไร แน่นอนว่าดีกว่าการพยายามเปลี่ยน C ++ เป็น Java

จุดเริ่มต้นที่ดีอีกประการสำหรับชุดโค้ดแนวทางคือC ++ Core Guidelines ใหม่ซึ่งเป็นงานที่อยู่ระหว่างดำเนินการโดย Bjarne Stroustrup และ Herb Sutter

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

มีเหตุผลสองประการที่คุณอาจจำเป็นต้องใช้สิ่งอื่นที่ไม่ใช่ Java จริงๆ:

  1. คุณต้องการประสิทธิภาพการทำงานจริงๆ ในกรณีนี้การรักษา C ++ เหมือน Java อาจจะไม่ช่วยคุณได้จริง ๆ เพราะเทคนิคเหมือน Java เช่นตัวชี้ที่ใช้ร่วมกันจะทำให้ประสิทธิภาพการใช้งานของคุณลดลง
  2. คุณต้องใช้ซอฟต์แวร์เพื่อทำงานบนแพลตฟอร์มที่ไม่ชัดเจนซึ่งยังไม่รองรับ JVM ในกรณีนี้คุณอาจติดอยู่กับภาษาที่มีส่วนหน้าของ GCC หรือ Clang C และ C ++ เป็นตัวเลือกที่ชัดเจน แต่คุณสามารถดูได้เหมือนสนิม (ปลั๊กด่วน: ฉันไม่ได้ใช้ Rust อย่างกว้างขวาง แต่มันก็ดูดีมากและฉันกระตือรือร้นที่จะทำงานในโครงการ Rust ที่สำคัญโดยเร็วที่สุดเท่าที่จะทำได้และฉันคิดว่าทุกคนที่พิจารณาเริ่มโครงการ C ++ ควรพิจารณา Rust เป็นทางเลือก)

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

ฉันพูดถึงเรื่องนี้มาบ้างแล้ว แต่ฉันตั้งใจทิ้งประโยคที่สองของคุณไว้

ฉันไม่มั่นใจว่าสิ่งที่ชอบconstexprซึ่งจะไม่สมเหตุสมผลในภาษา JIT บางส่วนเช่น Java เป็นตัวบ่งชี้สถาปัตยกรรมที่ไม่ถูกต้อง ฉันเปิดกว้างต่อความคิดที่ว่าการใช้เทมเพลตเมตาการเขียนโปรแกรมที่มากเกินไปอาจมีปัญหามากกว่าที่ควรเป็นโดยเฉพาะตอนนี้ที่constexprมีอยู่สำหรับการประเมินฟังก์ชั่นคอมไพล์เวลา แต่มันชัดเจนจากกรณีconstexprที่ไม่มีข้อบกพร่องในการออกแบบคุณกำลังใช้งานอยู่: คุณเพียงแค่ทำให้แน่ใจว่าการคำนวณบางอย่างเกิดขึ้นก่อนที่จะเรียกใช้รหัสซึ่งเป็นการเพิ่มประสิทธิภาพที่ยอดเยี่ยม (ดูตัวอย่างสำหรับรายการนี้สำหรับปัญหา n-body ของ The Benchmark Gameซึ่งมีประสิทธิภาพเหนือกว่าทุกรายการยกเว้นรายการอื่น เขียนใน C ++


5
ผู้เขียน FQA ตกอยู่ในกลุ่ม "เข้าใจมากที่สุด 20% ของภาษา" ค่อนข้างมีคำตอบอยู่บ้างที่ผิดจริงและมีอีกมากมายที่เพิ่งพลาดประเด็นซึ่งแสดงให้เห็นว่าชาวเยอรมันคนหนึ่งทำจากฟางฟาง
Ben Voigt

2
การร้องเรียนจำนวนมาก (เกือบทั้งหมด) ใน C ++ FQA นั้นไร้สาระ ภาษาสมัยใหม่มีขนาดใหญ่มาก C ++ ค่อนข้างเล็กเมื่อเปรียบเทียบกับ Python, Ruby, Perl และ yes, Java ถามคำถามพื้นฐานในภาษาเหล่านี้เกี่ยวกับ stackoverflow และคำตอบแรกนั้นเกือบจะหลีกเลี่ยงไม่ได้ในบรรทัดของ "ทำไมคุณimport SomeVeryBasicPackageไม่ทำอย่างนี้ ? ถามคำถามขั้นสูงและคำตอบแรกเกือบจะหลีกเลี่ยงไม่ได้ในบรรทัดของ "ทำไมคุณimport SomeMagicalPackageไม่ทำอย่างนั้น ?
David Hammen

1
@ DavidHammen ฉันคิดว่าการแบ่ง 80/20 หมายถึงคุณสมบัติภาษาหลักไม่ใช่แค่ส่วนประกอบไลบรารีมาตรฐานซึ่งในกรณีนี้ภาษาที่คุณพูดถึงด้วยข้อยกเว้นที่เป็นไปได้ของ Perl ดูเหมือนจะไม่ใหญ่และซับซ้อนเท่า C ++ ไม่ว่าในกรณีใดนั่นเป็นส่วนเล็ก ๆ ของคำตอบของฉันและฉันยอมรับว่ามันเป็นแหล่งที่มีอคติ
Kyle Strand

1
ภาษา VM / ภาษาที่จัดการมีความซับซ้อนมากขึ้นอย่างเห็นได้ชัดภายใต้พื้นผิว แต่ฉันหมายถึงความซับซ้อนจากมุมมองการใช้งาน
Kyle Strand

1
ฉันไม่รู้ว่าทฤษฎีของคุณถูกต้องหรือไม่ แต่ในกรณีของฉันฉันเรียนรู้ C ++ และ C แยกจากกันและชั้น C ++ ของฉันก็ค่อนข้างละเอียด แต่การอ้างถึงแบบเต็มเกี่ยวกับการแบ่ง 20/80 คือโปรแกรมเมอร์ทุกคนรู้ภาษาที่แตกต่างกัน 20% ซึ่งจะไม่สามารถอธิบายได้โดยโปรแกรมเมอร์ส่วนใหญ่ที่ได้รับการสอนส่วน C ของภาษาอิสระ อย่างไรก็ตามหากคุณต้องการอธิบายรายละเอียดว่า C ++ อนุญาตให้โปรแกรมมีประสิทธิภาพมากขึ้นได้อย่างไร (ฉันอ้างว่าฉันเคยเห็นมาก่อน แต่ไม่เข้าใจ) เราควรทำในห้องแชทหรืออะไรมากกว่าความคิดเห็นที่นี่ .
Kyle Strand

5

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

เลขที่

ถ้า "โดยสภาพแวดล้อมของโครงการ" คุณถูก จำกัด ให้ใช้ C ++ แล้วมีน้อยถ้ามีจุดในการคิดแม้แต่เกี่ยวกับเทคโนโลยีอื่น ๆ ไม่ว่าคุณอาจต้องการ / หวังว่าจะใช้ / ประกาศด้วยตนเองมากน้อยเพียงใด
ไม่ว่า "Technology X" หรือ "Y" รองรับคุณสมบัติใด ๆ ก็ตามไม่ควรมีปัญหาใด ๆกับวิธีที่คุณสร้างแอปพลิเคชัน C ++ ของคุณ
มันเป็นแอปพลิเคชั่น C ++ ที่น่าจะเป็นไปได้สำหรับ "Good Reason" (ตอนนี้หรือในอดีต) ดังนั้นคุณควรเขียนมันเป็นแอปพลิเคชั่น C ++ โดยใช้สิ่งที่ "กล่องเครื่องมือ" ที่ระบุ

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

มีการถกเถียง ("ใช้หรือไม่ใช้") ที่คล้ายกันหลายปีใน Visual Basic [.Net] โลกซึ่งมีคนคิดว่าคุณควรเขียนแอปพลิเคชัน Visual Basic โดยไม่ต้องใช้ [ภาษาหลัก] ใด ๆ ฟังก์ชันการทำงานที่มีให้โดย namespace Microsoft.VisualBasic มันเหมือนกับการพยายามเขียนแอปพลิเคชัน C ++ โดยไม่มี std :: namespace ตกลงเป็นไปได้ แต่ทำไมบนโลกนี้ถึงมีใครในใจที่ถูกต้องสนใจทำเช่นนั้น?


1
จนถึงจุดสุดท้ายของคุณเกี่ยวกับ Visual Basic: ปัญหาเกี่ยวกับไลบรารี่ของผู้จัดจำหน่ายคือพวกเขาเป็นเจ้าของ ใช้พวกเขาหมายถึงการผูกมัดตัวเองกับผู้ขายที่ ผู้จัดจำหน่ายจะชอบคุณถูกล่ามโซ่ แต่คุณจะไม่ได้ทำงานในระยะยาว: คุณไม่สามารถใช้ซอฟต์แวร์ของผู้ขายรายอื่นได้โดยไม่ต้องเขียนใหม่ทุกอย่างที่ต้องอาศัยการทำงานเฉพาะของผู้ขาย ยิ่งคุณใช้ฟังก์ชั่นเฉพาะของผู้จัดจำหน่ายมากเท่าไหร่ค่าใช้จ่ายในการเปลี่ยนผู้ขายก็จะยิ่งสูงขึ้น นั่นเป็นหนึ่งในเหตุผลที่ว่าทำไมซอฟต์แวร์เสรี (เป็นอิสระ!) นั้นเป็นเรื่องใหญ่
cmaster

Microsoft.VisualBasicสิ่ง namespace เป็นบิตของการยืด เป็นเวลาหลายปีแล้วที่ฉันใช้มันครั้งล่าสุด แต่อย่างน้อยตอนแรกมันก็มีจุดประสงค์หลักที่จะเข้ากันได้กับ VB6 (และ / หรือเพื่อให้โปรแกรมเมอร์ VB6 รู้สึก "ที่บ้าน"); มันส่วนใหญ่ให้ฟังก์ชั่นที่มีอยู่แล้วในส่วนที่เหลือของกรอบในรูปแบบที่ทันสมัย ​​(และบูรณาการที่ดีขึ้น) ดังนั้นในโครงการใหม่มันไม่ค่อยมีเหตุผลที่จะใช้มัน ในทางตรงกันข้ามstd::เนมสเปซเป็นที่ตั้งของไลบรารีมาตรฐานทั้งหมด - การหลีกเลี่ยงมันจะเหมือนกับการหลีกเลี่ยง BCL ทั้งหมดใน. NET
Matteo Italia

2

คำตอบปัจจุบันทั้งหมดบอกว่านี่เป็นสิ่งที่ไม่ดีที่คุณควรใช้ประโยชน์จากภาษาที่คุณใช้และอธิบายว่าเพราะเหตุใดคุณลักษณะ C ++ จึงไม่“ เลวร้าย” เพียงเพราะมันไม่ได้อยู่ใน jave ฉันจะตอบคำถามนี้จากมุมที่แตกต่าง

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

แต่ปัญหาที่ทำมากกว่างานง่ายที่สุด:

  • จัดสรรหน่วยความจำ
  • เชื่อมต่อเงินนั้นเข้ากับคะแนน
  • ดังนั้นสร้างโครงสร้างข้อมูล
  • จากนั้นอนุญาตให้นำหน่วยความจำกลับมาใช้ใหม่ได้เมื่อปลอดภัย

ไม่มีชุดย่อยทั่วไปของ Java และ C ++ ที่อนุญาตข้างต้นดังนั้นสิ่งที่คุณขอเป็นไปไม่ได้ที่จะทำ (ถ้าคุณถามเกี่ยวกับ Java และ C # คุณจะมีโอกาสมากขึ้นเพราะทั้งคู่ใช้ตัวรวบรวมขยะ)

อย่างไรก็ตามคุณอาจต้องการให้เขียนโค้ดเพื่อให้ผู้พัฒนา Java สามารถเข้าใจสิ่งที่ทำ (แต่ไม่ใช่รายละเอียด "วิธี") และสิ่งนี้จะสมเหตุสมผล

คุณสามารถออกแบบภาษาของคุณเองที่คุณติดตั้งได้ทั้ง C ++ และ JAVA .....


0

ไม่มีใครควรเขียนโค้ดใด ๆ ที่ผู้เขียนโค้ดคนอื่นไม่เข้าใจ หากคุณคิดว่าการล็อคภาษาเป็นปัญหาให้รอจนกว่าคุณจะมีล็อคนักพัฒนาซอฟต์แวร์ หนึ่งมีแนวโน้มที่จะถือตัวประกันคุณมากกว่าคนอื่น

ไม่มีเหตุผลทางเทคนิคจริงๆ สิ่งที่คุณสร้างขึ้นคือสถานการณ์ที่ใช้ภาษาไม่ว่าจะด้วยเหตุผลใด แต่ผู้พัฒนาในปัจจุบันและที่เป็นไปได้หลายคนอาจไม่เข้าใจจริงๆ

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

นี่เป็นข้อโต้แย้งเกี่ยวกับปัญหาของโปรแกรมเมอร์พื้นฐานที่ย้ายไปยังภาษาเชิงวัตถุ ไม่ใช่ว่าพวกเขาใช้แนวปฏิบัติของ OOP ที่สร้างความเสียหายให้กับผู้พัฒนารายใหม่ที่ไม่เข้าใจ แต่พวกเขาก็ไม่ได้นำไปใช้เลย ถ้าพวกเขาทำพวกเขามักจะเข้าใจผิด หากสิ่งใดที่ทำไม่ดีจะต้องลบออกโดยไม่คำนึงถึงเหตุผล

นอกเหนือจากคนที่เพิ่งคัดลอกและวางรหัสอย่างสุ่มสี่สุ่มห้าพวกเขาจะทำในหลายพื้นที่ที่พวกเขาไม่เข้าใจ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.