อะไรคือความแตกต่างพื้นฐานระหว่าง C และ C ++ [ปิด]


41

หลายคนมักจะเขียน "C / C ++" ราวกับว่าพวกเขาเป็นสิ่งเดียวกัน แม้ว่าพวกเขาจะมีความคล้ายคลึงกันมากมาย แต่ก็ไม่เหมือนกันอย่างชัดเจน

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


2
ฉันคิดว่า C ++ เป็นชุดสุดยอดของ C
ผู้ใช้

1
C ++ ไม่ได้รับการพัฒนา ... มันคือ superset of C ..
Joe DF

2
@ JoeDF มันเป็นจุดเริ่มต้นมาก แต่จริง ๆ แล้ว "เข้ากันได้กับ C" ตอนนี้ซึ่งไม่ได้หมายความว่าสิ่งเดียวกันเลย คุณไม่ได้รหัสใน C ใน C ++ และไม่ได้มาตรฐาน C ทั้งหมดเข้ากันได้กับ C ++ มาตรฐาน
Klaim

+1 คุณถูกต้องตอนนี้เหมือนพี่น้องหรือญาติ ถ้าคุณรู้ว่าฉันหมายถึงอะไร.
Joe DF

คำตอบ:


43

ประเด็นต่อไปนี้เกี่ยวข้องกับ C ++:

  1. ระบบกำหนดชนิดคงที่ (ผู้ใช้กำหนด):อนุญาตให้ตรวจสอบแบบคงที่เกี่ยวกับข้อมูลและการใช้งานของพวกเขา - ชี้ข้อผิดพลาดที่ทำได้ง่ายจำนวนมากใน C.
  2. multi- "กระบวนทัศน์": อนุญาตให้ทำงานเหมือนใน C กับกระบวนทัศน์เชิงวัตถุแบบกระบวนทัศน์ทั่วไปเป็นต้น
  3. Constructor / Destructor:วิธีเดียวที่จะบอกเมื่อทำอะไรเมื่อสร้างหรือทำลายบางสิ่งบางอย่างและให้แน่ใจว่าผู้ใช้จะไม่ต้องค้นหาฟังก์ชั่นที่เหมาะสมและใช้งานได้เหมือนใน C
  4. RAII (ชื่อไม่ดี):คุณไม่จำเป็นต้องจัดการหน่วยความจำเสมอ เพียงเก็บสิ่งต่าง ๆ ไว้ในขอบเขตและใช้สมาร์ทพอยน์เตอร์ที่อธิบายถึงอายุการใช้งานของวัตถุของคุณ ยังคงสามารถใช้ตัวชี้แบบดิบ
  5. เทมเพลต:ดีกว่าแมโครซึ่งเป็นภาษาจริงในการจัดการและสร้างชนิดก่อนการรวบรวมขั้นสุดท้าย ขาดระบบพิมพ์เท่านั้น (ดูแนวคิดในมาตรฐาน C ++ ในอนาคต)
  6. ตัวดำเนินการโอเวอร์โหลด:ช่วยให้สามารถอธิบายการดำเนินการในลักษณะประโยคอย่างง่ายและแม้กระทั่งการกำหนดภาษาเฉพาะโดเมนแบบฝังในรหัส C ++ ของคุณ
  7. ชื่อที่กำหนดขอบเขต:เนมสเปซ, คลาส / โครงสร้าง, ฟังก์ชัน ฯลฯ มีกฎง่าย ๆ เพื่อให้แน่ใจว่าชื่อจะไม่ขัดแย้งกัน
  8. ระบบการยกเว้น:วิธีการเผยแพร่ข้อผิดพลาดที่มักจะดีกว่าโค้ดส่งคืน ในความเป็นจริงรหัสส่งคืนนั้นดีสำหรับข้อผิดพลาดเชิงตรรกะเฉพาะโดเมนเนื่องจากแอปพลิเคชันมีการจัดการ ข้อยกเว้นใช้สำหรับข้อผิดพลาด "ยาก" สิ่งต่าง ๆ ที่ทำให้รหัสต่อไปนี้ไม่ถูกต้อง จะช่วยให้จับข้อผิดพลาดที่สูงขึ้นใน call stack ถ้าเป็นไปได้ตอบสนองต่อข้อยกเว้นดังกล่าว (โดยการบันทึกหรือแก้ไขสถานะ) และกับ RAII ถ้าใช้ดีจะไม่ทำให้โปรแกรมทั้งหมดผิด - ถ้าทำได้ดีอีกครั้ง
  9. ไลบรารีมาตรฐาน: C มีของตัวเอง แต่เป็น "แบบไดนามิก" ทั้งหมด ไลบรารีมาตรฐาน C ++ นั้นเกือบ (ไม่ใช่ IO stream) ที่ทำจากเทมเพลต (คอนเทนเนอร์และอัลกอริธึม) ที่อนุญาตให้สร้างโค้ดสำหรับสิ่งที่คุณใช้เท่านั้น ดีกว่า: เนื่องจากคอมไพเลอร์ต้องสร้างโค้ดมันจะรู้มากเกี่ยวกับบริบทและจะใช้การเพิ่มประสิทธิภาพอย่างมากโดยไม่ต้องใช้ coder เพื่อทำให้งงงวยรหัส - ขอบคุณแม่แบบและสิ่งอื่น ๆ
  10. const-correctness:วิธีที่ดีที่สุดที่จะทำให้แน่ใจว่าคุณจะไม่เปลี่ยนแปลงตัวแปรที่คุณไม่ควรทำ อนุญาตให้ระบุการเข้าถึง varaibles แบบอ่านอย่างเดียว และมันจะถูกตรวจสอบในเวลารวบรวมเท่านั้นดังนั้นจึงไม่มีค่าใช้จ่ายรันไทม์

31

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

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

C ++ ช่วยโดยการมีวัตถุ init constructor ซึ่งถูกเรียกโดยอัตโนมัติโดยคอมไพเลอร์ แตกต่างจาก C structs ที่ต้องเริ่มต้นโดยโปรแกรมเมอร์ (ดังนั้นพื้นที่ข้อผิดพลาดอื่นได้ง่าย)

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

และสิ่งอื่น ๆ อีกมากมายที่ต้องใช้เวลาในการเขียนรายการที่นี่มากเกินไป


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

คุณมีประเด็นอยู่ที่นั่น แต่จุดเน้นของคำตอบของฉันที่นี่คือ C กับ C ++
Jas

1
ใครมาขัดขวางไม่ให้คุณใช้ OOP กับ C? คุณสามารถนำวัตถุกลับมาใช้ใหม่และทำสิ่งใดก็ได้ มีแม้กระทั่งหนังสือเกี่ยวกับมันที่เรียกว่าการเขียนโปรแกรม OOP ใน C.

2
@ วลาดไม่มีสิ่งที่คุณกำลังพูดถึงเป็นตัวเลือก 25 ปีที่แล้ว
Jas

4
คุณสามารถทำ OOP ในภาษาการเขียนโปรแกรมเกือบทุกภาษาที่ยังใช้งานอยู่ แต่ไม่ได้หมายความว่าภาษานั้นถูกออกแบบมาสำหรับมัน ยกตัวอย่าง Lua ในขณะที่เทคนิคอนุญาตให้ใช้ OOP ได้ดูเหมือนว่ามีวิธีการทำแตกต่างกันประมาณ 50 วิธีซึ่งเป็นสาเหตุของอาการปวดหัว
tyjkenn

15

โดยทั่วไปทุกอย่างที่มีอยู่ใน C ได้รับการสนับสนุนใน C ++ แน่นอนว่าสิ่งที่ตรงกันข้ามนั้นเป็นเท็จอย่างแน่นอน

เพียงแค่พูด C ++ เป็นเชิงวัตถุ (เช่นคุณมีคลาส) และ C ไม่ใช่

C ++ มีประเภทบูลีน C89 ไม่ได้

พวกเขาเป็นภาษาที่แตกต่างกัน พวกเขาเพียงแชร์ไวยากรณ์ส่วนใหญ่


4
C99 มีชนิดบูลีน (ชื่อ_Boolด้วยการboolเป็นชื่อแทน)
Jerry Coffin

1
นี่ไม่เป็นความจริงอย่างเคร่งครัด ตัวอย่างเช่น C99 มีlong longประเภทข้อมูลที่ยังไม่ได้เป็นส่วนหนึ่งของ ISO C ++
Chinmay Kanchi

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

4
มีโครงสร้างจำนวนมากใน C ที่ไม่ทำงานใน C ++

1
@klez: ใช่ - แต่มันก็ผิด ในขณะที่ ANSI พัฒนา C89 (ซึ่งไม่มีประเภทบูลีน) ตอนนี้การพัฒนาใหม่ทำโดย ISO และ ANSI ยอมรับมาตรฐาน ISO ดังนั้นมาตรฐาน ANSI C ปัจจุบันจึงเหมือนกับมาตรฐาน ISO C ปัจจุบัน (ซึ่งมี ประเภทบูลีน)
Jerry Coffin

8

C99 มีคุณสมบัติบางอย่างที่ไม่มีอยู่ (อย่างน้อยก็ในรูปแบบเดียวกัน) ใน C ++ (เช่นสมาชิกอาเรย์แบบยืดหยุ่นอาร์เรย์ความยาวผันแปรเป็นต้น)

C99 ยังเพิ่มไลบรารีจำนวนมากที่ไม่ได้อยู่ในมาตรฐาน C ++ 98/03 ส่วนใหญ่นี้ได้รับการเพิ่มใน C ++ 11

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


1

โดยส่วนตัวแล้วฉันคิดว่าเทมเพลตเป็นคุณสมบัติที่สำคัญที่สุดที่ C ++ เพิ่มเข้ากับ C


1
เอ้อแล้วคลาสกับมรดกล่ะ นั่นเป็นงานที่ยากจริงๆใน C ในขณะที่เทมเพลตจำนวนมากสามารถทำได้ด้วยมาโครโปรเซสเซอร์ก่อน
JBRWilkinson

4
มาโครตัวประมวลผลล่วงหน้าไม่ปลอดภัยต่อประเภท; เป็นการทดแทนข้อความที่บริสุทธิ์ซึ่งทำให้การแก้จุดบกพร่องยากขึ้น เพื่อให้ได้คลาสพื้นฐานและการสืบทอดการทำงานไม่ใช่งานใน C + คุณต้องสร้างโมเดล metaobject ของคุณเองแทนที่จะติดอยู่กับสิ่งที่นักออกแบบภาษาเลือกให้คุณ ตัวอย่างเช่นดูบทความนี้: arxiv.org/abs/1003.2547
zvrba

2
การลงคะแนนของฉันจะเป็นสิ่งทำลายล้างสำหรับคุณลักษณะที่สำคัญที่สุด C ++ ที่มีมากกว่า C (หรือมากกว่าตัวสร้างเนื่องจากความสามารถในการล้างข้อมูลที่น่าทึ่ง)
Thomas Eding

@zvrba #define GENERATE_INTERFACE(T) T T##_func(T x);; (ประเภท) การโหลดมากเกินไป / เทมเพลตอย่างปลอดภัยใน C. ฉันเห็นด้วยกับ Thomas ว่า destructors เป็นคุณสมบัติที่สำคัญยิ่งกว่า C หายไป แต่ destructors มักจะซ่อนรหัสสำคัญ เนมสเปซ (ขอบเขต) เป็นสิ่งที่สำคัญที่สุดสำหรับฉัน
YoYoYonnY
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.