เหตุใด C ++ ยังคงเป็น“ ลูกผสม”


16

สำหรับคำถามที่เกี่ยวข้องจะได้รับการชี้แจงว่าทำไม C ++ เข้ากันไม่ได้กับ C ในหลาย ๆ ด้าน อย่างไรก็ตาม C ++ ยังคงเป็นภาษา "ไฮบริด" * และน่าเสียดายที่โปรแกรมเมอร์หลายคนยังถือว่า C ++ เป็น "C ที่มีสตรีมและสตริงในตัว" ผลลัพธ์นั้นเป็นโค้ดที่เขียนไม่ดีจริง ๆ ซึ่งไม่ใช่ทั้ง C ++ หรือ C. IMHO มันจะดีกว่าถ้าภาษา / คอมไพเลอร์บังคับให้โปรแกรมเมอร์ในระดับหนึ่งต้องเขียนโค้ดที่หรูหรากว่านี้ ดังนั้นมีเหตุผลในการรักษาไฮบริด C ++ (เช่น C ++ 0x และเวอร์ชันในอนาคต) ไฮบริด?

* โดยไฮบริดฉันหมายถึงมันขึ้นอยู่กับโปรแกรมเมอร์ที่จะตัดสินใจว่าเขา / เธอจะใช้หรือไม่: สตริงมาตรฐานและสตรีม, คลาส, เนมสเปซอื่นที่ไม่ใช่ค่าเริ่มต้นเป็นต้น


มีการตั้งค่าคอมไพเลอร์ / IDE ที่มีอยู่ซึ่งสามารถบังคับใช้ได้หรือไม่
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner ฉันไม่ได้ตระหนักถึงเครื่องมือใด ๆ ที่ทำเช่นนั้น แต่มันจะเหมาะสมกว่าที่จะเขียนเครื่องมือ (คอมไพเลอร์, IDE และอื่น ๆ ) ถ้าคุณสมบัติเหล่านั้นเป็นส่วนมาตรฐาน C ++
sakisk

2
Raison d'etre ของ C ++ นั้นสามารถใช้งานร่วมกับระบบย้อนหลังได้และมีความเป็นไปได้ที่จะใช้ลูกเล่นสกปรกทั้งหมดที่เป็นไปได้ใน C นำมันออกไปและมันก็เป็นอีก C #, D หรือ Java clone หากคุณต้องการสิ่งนั้นทำไมไม่ใช้ C #, D หรือ Java?
nikie

5
@nikie: ฮ่า ๆ ๆ ๆ เนื่องจากเทมเพลตประเภทค่าการอ้างอิงที่คาดเดายากการทำลายล้างอย่างกำหนดค่าการรับมรดกจำนวนมากความเร็วในการดำเนินการการใช้หน่วยความจำต่ำสิ่งเหล่านี้จึงไม่มีอยู่จริง
DeadMG

2
@ นิกกี้: ยกเว้น D ยังมีสิ่งที่น่ารังเกียจเช่นObjectและค่าคัดลอกไบนารีและอาร์เรย์ที่เชื่อมโยงกับภาษา (ทำไม ... ) พร้อมกับการตัดสินใจออกแบบที่น่าสงสัยอื่น ๆ ของตัวเอง นอกจากนี้มันยังมีกระบวนทัศน์ GC แบบเดียวกับที่อื่น ๆ ดังนั้นฉันจึงตั้งคำถามว่าการใช้หน่วยความจำต่ำ
DeadMG

คำตอบ:


26

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


1
แน่นอน แต่เนื่องจากเป็นเพียงรหัสดั้งเดิมทำไมรุ่น C ++ รุ่นใหม่จึงจำเป็นต้องใช้งานร่วมกันได้ รหัสดั้งเดิมยังคงสามารถใช้ C ++ รุ่นเก่ากว่าได้
sakisk

15
@faif ในงานของฉันฉันเขียนรหัส C ++ ใหม่ตลอดเวลาที่ต้องติดต่อกับรหัส C ใหม่ มันไม่ใช่แค่ปัญหาดั้งเดิม
Karl Bielefeldt

5
@faif: C ++ รุ่นที่ใหม่กว่าต้องสามารถใช้งานร่วมกันได้ - ไม่เพียง แต่รองรับรหัส C รุ่นเก่า แต่ยังมีรหัส C ++ ที่มีอยู่อีกหลายร้อยล้านบรรทัด หากคุณต้องการบางสิ่งที่ไม่เข้ากันได้แบบย้อนกลับ แต่ได้รับการออกแบบที่ดีกว่าคุณมีอิสระที่จะเปลี่ยนเป็นภาษาอย่าง D. โดยวิธีต่อไปนี้เป็นบทความที่ดีมากเกี่ยวกับความต้องการความเข้ากันได้แบบย้อนหลังของ Joel Spolsky: joelonsoftware.com/items/2008 /03/17.html
Doc Brown

4
The best we can do is make it easy to write good code.- เรากำลังพูดถึง C ++ เดียวกันหรือไม่
BlueRaja - Danny Pflughoeft

4
@ BlueRaja-DannyPflughoeft: ฉันคิดว่ามันง่ายกว่าในการเขียนโค้ดที่ดีใน C ++ มากกว่าใน Java หรือ C # ด้วย C ++ ฉันสามารถอ่านคลาสได้และถ้าคลาสอื่น ๆ ทำงานฉันรู้ว่าหน่วยความจำและทรัพยากรจะไม่ถูกรั่ว ด้วย Java และ C # ฉันไม่สามารถทำได้ ฉันต้องไปตรวจสอบคลาสอื่น ๆ เพื่อดูว่ามีคลาสใดที่จำเป็นต้องมีการสรุป เทมเพลต C ++ ยังแจ้งให้ฉันทราบถึงโค้ดที่ต้องทำซ้ำใน Java
วินไคลน์

20

IMHO มันจะดีกว่าถ้าภาษา / คอมไพเลอร์บังคับให้โปรแกรมเมอร์บางส่วนเขียนโค้ดที่สวยงามกว่านี้

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

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

ยวดมาตรฐานสตริงและสตรีมชั้นเรียนจริงดูด std::stringไม่มีการสนับสนุน Unicode และอินเทอร์เฟซป่องที่แย่ที่สุดที่คุณอาจจินตนาการได้ ลำธารมีค่าใช้จ่ายที่น่ากลัวและการออกแบบที่ไม่ดีแม้แต่หันไปใช้การสืบทอดเสมือนจริงและพอยน์เตอร์ฟังก์ชั่นและconst char*และน่าเกลียดเช่นนั้น ฉันจะไม่ลงโทษใครเลยที่จะแทนที่ทั้งคลาส / กลุ่มคลาสเหล่านั้นด้วยค่าที่กำหนดเอง

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


+1 สำหรับแนวทางที่ค่อนข้างสมจริง (หยุดพูดคุย "รหัสที่สง่างาม": /
Rook

2
"รูปแบบการเข้ารหัสที่บังคับใช้กับภาษานั้นแย่มากจริงๆ" คุณยกตัวอย่างได้บ้าง ฉันคิดว่าแม้แต่เรื่องง่าย ๆ เช่นการเยื้องรหัสที่บังคับใช้ของ Python ช่วยเพิ่มความสามารถในการอ่านโค้ด
sakisk

3
ฉันไม่แน่ใจว่าฉันเห็นด้วยกับสิ่งนี้หรือไม่ เหตุผลหลักในการใช้ CoffeeScript ผ่าน JavaScript เป็นเพราะ CoffeeScript ได้รับการออกแบบมาเพื่อบังคับใช้การเขียนโค้ดที่หรูหรากว่า
user16764

3
ไม่เห็นด้วยกับสิ่งนี้ การออกแบบภาษาบางอย่างนั้นมีจุดประสงค์เพื่อสนับสนุนการปฏิบัติที่ดีและธรรมชาติที่แผ่ขยายออกไปของสิ่งมีชีวิตส่วนใหญ่ของภาษาซีพลัสพลัสจะทำให้หมดไป ในความเป็นจริงการเลือกสรรภาษา, การรักษาส่วนที่ดีและการปรับปรุงส่วนที่เหลือเป็นแรงจูงใจหลักที่อยู่เบื้องหลังการดำรงอยู่ของC ++ 11
Robert Harvey

1
@Pubby: "การเขียนโปรแกรมที่น่าเกลียดที่ใช้งานได้ดีกว่าการเขียนโปรแกรมที่สวยงามที่ไม่ทำอะไรเลย" แน่นอนว่าฉันสามารถเห็นด้วยกับที่ แต่บทความนี้ไปไกลกว่านั้นและดูเหมือนว่าจะโต้แย้งว่าความอัปลักษณ์นั้นเป็นคุณธรรม และมันก็ไร้สาระ
Mason Wheeler

8

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

IMHO มันจะดีกว่าถ้าภาษา / คอมไพเลอร์บังคับให้โปรแกรมเมอร์บางส่วนเขียนโค้ดที่สวยงามกว่านี้

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

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

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


1
ไม่สามารถตกลงเพิ่มเติม ฉันคิดว่าเมื่อมีคนพูดว่า "C ++ ยืดหยุ่น" ฉันจะคิดอย่างนั้นเพราะมันสนับสนุนกระบวนทัศน์มากกว่าที่ C ทำ
prelic

5

IMHO มันจะดีกว่าถ้าภาษา / คอมไพเลอร์บังคับให้โปรแกรมเมอร์บางส่วนเขียนโค้ดที่สวยงามกว่านี้

ไม่มีใครบังคับให้ใครใช้ C ++ ตั้งแต่แรก หากภาษาไม่เหมาะกับคุณให้ใช้ภาษาอื่น - มีหลายภาษาที่เรียกเก็บเงินเป็น "C ++ ไม่มี C"

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

ความเข้ากันได้ของ C ++ กับ C นั้นเป็นหนึ่งในจุดอ่อนที่สุด แต่ก็จำไว้ด้วยว่ามันเป็นหนึ่งในจุดที่ดีที่สุด


ฉันจะเพิ่มคำพูดที่ยอดเยี่ยมโดย Jon Purdy ซึ่งฉันรู้สึกว่ามีความเกี่ยวข้องมาก:

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

การนำไฮบริดออกอาจช่วยเพิ่มความสวยงาม แต่ก็เป็นอุปสรรคต่อความสามารถ


คุณเชื่อว่าลัทธิปฏิบัตินิยมและความสง่างามขัดแย้งหรือไม่? ฉันคิดว่า Python, Ruby และ Scala เป็นตัวอย่างที่ดีของภาษาที่มีทั้งในทางปฏิบัติและสง่างาม
sakisk

1
@faif: ไม่ แต่ความเข้ากันได้แบบย้อนหลังและความสง่างามนั้นขัดแย้งกัน สิ่งนี้ใช้ได้กับ Python ด้วย (2.x กับ 3.x)
dan04

4

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

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

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


2

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

ในฐานะโปรแกรมเมอร์เราบางครั้งลืมวิธีที่ดีที่สุดอาจไม่ใช่เทคนิค ความคิดเห็นจากเพื่อนเป็นทางออกที่รู้จักกันดีในกรณีนี้


0

C ++ ไม่มี "ทางเดียวที่แท้จริง"; ทุกวิธีมีจุดแข็งและจุดอ่อน การแก้ปัญหาสามารถเขียนได้หลายร้อยวิธี

คุณในฐานะนักพัฒนาซอฟต์แวร์ต้องตัดสินใจว่าวิธีใดเหมาะสมที่สุดสำหรับงานในมือ


0

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

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

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

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

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