C แตกต่างจาก C ++ อย่างไร


21

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


3
เนื่องจากวิธีการใช้งาน แน่นอนคุณสามารถเขียน C ใน C ++ ... แต่คุณไม่ควร
Ed S.

คำตอบ:


18

ในช่วงปี 1980 เมื่อการพัฒนา C ++ เพิ่งเริ่มต้นขึ้น C ++ นั้นเกือบจะเป็น superset ที่เหมาะสมของ C นั่นคือวิธีที่มันเริ่มต้นขึ้นทั้งหมด
อย่างไรก็ตามเมื่อเวลาผ่านไปทั้ง C และ C ++ ได้รับการพัฒนาและแยกออกจากกันแม้ว่าความเข้ากันได้ระหว่างภาษานั้นมีความสำคัญเสมอ

นอกจากนี้ความแตกต่างทางเทคนิคระหว่าง C และ C ++ ทำให้สำนวนทั่วไปในภาษาเหล่านั้นและสิ่งที่ถือว่าเป็น 'การปฏิบัติที่ดี' แตกต่างกันมากยิ่งขึ้น

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


ฉันไม่คิดว่าย่อหน้าแรกถูกต้อง ฉันเชื่อว่า C มักจะมีการคัดเลือกโดยปริยายvoid *แต่ C ++ ไม่เคยทำ (ไม่ได้ลงคะแนน)
ทางเลือก

5
@ คณิตศาสตร์: กำหนด "เสมอ" C ใช้ void * type จาก C ++ ใน K&R C, malloc กลับมาเป็นถ่าน *
Nemanja Trifunovic

19

Stroustrup ตอบว่าในคำถามที่พบบ่อยของเขา :

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

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

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


"นั่นไม่เหมือนสิ่งที่คุณเห็นใน C. " วลีนี้ฟังดูตลก! "เห็นใน C" C ใน C! นี่คือบทกวีชนิดหนึ่ง
Galaxy

13

พูดง่ายๆคือสิ่งที่ถือว่าเป็นสำนวนใน C ไม่แน่นอนใน C ++

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

นอกจากนี้ยังมีความแตกต่างในทางปฏิบัติ: C สามารถเรียกได้อย่างง่ายดายจากภาษาใด ๆ และมักจะกำหนด ABI ของแพลตฟอร์มในขณะที่ C ++ นั้นค่อนข้างยากที่จะใช้จากไลบรารีอื่น ภาษาส่วนใหญ่มี FFI หรือส่วนต่อประสานใน C แม้แต่ภาษาที่นำมาใช้ใน C ++ (ตัวอย่างเช่น java)


4
ไม่ใช่แค่ว่ารหัส C-style นั้นไม่ใช้สำนวนในภาษา C ++ การเข้ารหัสแบบ C นั้นเป็นปัญหาใน C ++ เนื่องจากการขาดข้อยกเว้นด้านความปลอดภัย
dan04

4

นอกเหนือจากความจริงที่ชัดเจนว่า C ++ รองรับการเขียนโปรแกรมเชิงวัตถุฉันคิดว่าคุณมีคำตอบของคุณที่นี่: http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++

บทความนั้นมีตัวอย่างโค้ดที่แสดงเนื้อหาที่ใช้ได้ใน C แต่ไม่ใช่ใน C ++ ตัวอย่างเช่น

int *j = malloc(sizeof(int) * 5); /* Implicit conversion from void* to int* */

การย้ายโปรแกรม C ไปยัง C ++ มักจะตรงไปตรงมาและส่วนใหญ่ประกอบด้วยการแก้ไขข้อผิดพลาดในการคอมไพล์ (เพิ่มการกระจาย, คำหลักใหม่ ฯลฯ )


4
การย้ายโปรแกรมเช่นนั้นไม่ได้ให้โปรแกรม C ++ แก่คุณ มันให้ C ที่สามารถคอมไพล์บนคอมไพเลอร์ C ++ ที่ไม่ได้ทำให้มัน C ++ (ฉันจะยังคงเรียกรหัสผลลัพธ์ C (ไม่แม้แต่ C กับชั้นเรียน))
Martin York

@ MartinYork เรียกมันว่า C ไม่ดีชี้ให้เห็นว่าความหมายอาจแตกต่างกันและฉันก็เห็นด้วย ผลที่ได้คือชัดแม้ว่า C
Deduplicator

2

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


2

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


คุณสามารถระบุตัวอย่างของหนึ่งในคุณสมบัติที่มีประโยชน์ที่ C ++ มี C นั้นไม่ได้หรือไม่?
Dark Templar

2
@DarkTemplar: การจัดการทรัพยากรแบบง่าย ๆ ด้วย RAII อย่างไร หรือโครงสร้างข้อมูลทั่วไปที่ดีโดยใช้แม่แบบ? เพียงแค่เริ่มต้นด้วย
DeadMG

1

ความแตกต่างคือใน C คุณคิดว่าโพรซีเดอร์และใน C ++ คุณคิดในรูปแบบของวัตถุ ภาษาค่อนข้างคล้ายกัน แต่วิธีการนั้นแตกต่างกันมาก


C ไม่มีโครงสร้างเช่นกันหรือ ไม่ใช่ไฟล์ C ที่แยกโมดูลเอง (โดยทั่วไปวัตถุ) ไม่แน่ใจว่าความแตกต่างที่ชัดเจนระหว่างขั้นตอนและเชิงวัตถุคืออะไร
Dark Templar

1
มืดคุณได้แสดงจุดของฉัน ไม่ใช่ข้อ จำกัด ของภาษาที่อนุญาตให้คุณเขียนขั้นตอนหรือในลักษณะที่เป็นวัตถุมันเป็น ethos หรือวิธีคิด
Ant

0

ในขณะที่ C ++ สามารถเป็นชุด C ที่ยอดเยี่ยมในด้านคำศัพท์ - เช่นการสร้างโปรแกรม C ใด ๆ ที่สามารถคอมไพล์โดยคอมไพเลอร์ C ++

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

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

ควรทำอย่างไรใน C ++ เหนือ C

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

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

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

  4. ใหม่ & ลบกับ malloc และฟรี คำสั่งใหม่ () และลบ () ไม่เพียงจัดสรรและยกเลิกการจัดสรรหน่วยความจำเท่านั้น แต่ยังอนุญาตให้ใช้รหัสในการดำเนินการในส่วนของ destruct-er ที่จะถูกเรียกในเชน หากคุณใช้ C ++ - เป็น BAD จริง ๆ แล้วใช้ malloc และฟรี

  5. ประเภท IO และการบรรทุกเกินพิกัดของผู้ปฏิบัติงานการบรรทุกเกินพิกัดทำให้โค้ดอ่านหรือง่ายขึ้นหากทำได้ดี เช่นเดียวกับตัวดำเนินการ << และ >> io วิธี C ในการทำเช่นนี้คือการใช้ตัวชี้ฟังก์ชั่น - แต่มันยุ่งและสำหรับโปรแกรมเมอร์ขั้นสูงเท่านั้น

  6. ใช้ "สตริง" char * จาก C ทำงานได้ทุกที่ ดังนั้น C และ C ++ ก็เหมือนกันมาก อย่างไรก็ตามถ้าคุณอยู่ใน C ++ - จะดีกว่ามาก (และปลอดภัยกว่า) ในการใช้คลาส String ซึ่งจะช่วยคุณให้พ้นจากอันตรายของอาร์เรย์ที่มีต่อการทำงานซึ่งเกือบทุกอย่าง

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

  1. ตัวชี้สมาร์ท - ใช่พวกเขาฉลาดมาก! และชอบสิ่งที่ฉลาดที่สุด - พวกเขาเริ่มต้นที่ดีและยุ่งเหยิงในภายหลัง! ฉันไม่ชอบที่จะใช้

สิ่งที่ฉันชอบเกี่ยวกับ C และพลาดใน C ++

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

  2. กระทู้ง่าย ๆ เมื่อคุณสร้างกระทู้เป็น pthreads - มันค่อนข้างง่ายและจัดการได้ มันจะกลายเป็นเมื่อคุณต้องการสร้างกระทู้ซึ่งควรจะเป็น "ส่วนตัว" ในชั้นเรียน (เพื่อให้พวกเขามีการเข้าถึงสมาชิกส่วนตัว) มีกรอบบูสต์เพิ่ม - แต่ไม่มีอะไรใน C ++ พื้นฐาน

Dipan


0

ฟีเจอร์ภาษาบางอย่างแม้ว่าจะเป็นสิ่งที่เพิ่มเข้ามาก็สามารถเปลี่ยนวิธีการใช้ภาษาได้อย่างแท้จริง จากตัวอย่างหนึ่งให้พิจารณากรณีนี้:

lock_mutex(&mutex);

// call some functions
...

unlock_mutex(&mutex);

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

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

void f(const Foo* f1)
{
    Foo f2;
    memcpy(&f2, f1, sizeof f2);
    ...
}

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

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

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

ฉันชอบ C ++ บ่อยกว่า แต่ฉันจริง ๆ ต้องใช้ C APIs ค่อนข้างบ่อยสำหรับความเข้ากันได้ของไบนารีที่กว้างที่สุด (และสำหรับ FFIs) แม้ว่าฉันมักจะใช้พวกเขาใน C ++ ทั้งๆที่ใช้ C สำหรับส่วนหัว แต่บางครั้งเมื่อคุณไปในระดับต่ำจริง ๆ เช่นระดับของตัวจัดสรรหน่วยความจำหรือโครงสร้างข้อมูลระดับต่ำมาก (และฉันแน่ใจว่ามีตัวอย่างเพิ่มเติมในหมู่ผู้ที่เขียนโปรแกรมฝังตัว) บางครั้งมันอาจเป็นประโยชน์ สามารถสันนิษฐานได้ว่าประเภทและข้อมูลที่คุณทำงานด้วยนั้นขาดคุณสมบัติบางอย่างเช่น vtables, costructors และ destructors เพื่อให้เราสามารถปฏิบัติต่อพวกเขาเป็นบิตและไบต์เพื่อสลับไปมาคัดลอกฟรีจัดสรรใหม่ สำหรับปัญหาระดับต่ำโดยเฉพาะอย่างยิ่งบางครั้งมันอาจเป็นประโยชน์ในการทำงานกับระบบประเภทที่ง่ายกว่าที่ C ให้

ชี้แจง

หนึ่งความคิดเห็นที่น่าสนใจที่นี่ฉันต้องการที่จะตอบสนองในเชิงลึกอีกเล็กน้อย (ฉันพบว่าความคิดเห็นที่นี่เข้มงวดมากกับจำนวนอักขระ):

memcpy(&f2, f1, sizeof f2); ยังเป็น "ขุมพลังแห่งหายนะ" ใน C หาก Foo มีพอยน์เตอร์ที่เป็นเจ้าของหรือแย่กว่านั้นเนื่องจากคุณขาดเครื่องมือในการจัดการกับสิ่งนั้น

นั่นเป็นประเด็นที่ยุติธรรม แต่ทุกสิ่งที่ฉันสนใจอยู่นั้นมีความสำคัญกับระบบประเภทของ C ++ และด้วยความเคารพ RAII หนึ่งในเหตุผลที่เช่น X-rayish ไบต์การคัดลอกmemcpyหรือqsortประเภทของการทำงานก่อให้เกิดน้อยของอันตรายในทางปฏิบัติใน C คือการทำลายf1และf2ข้างต้นเป็นอย่างชัดเจน (ถ้าพวกเขาจำเป็นต้องมีการทำลายที่ไม่น่ารำคาญ) ในขณะที่เมื่อ destructors ย้ายเข้าไปอยู่ในภาพ พวกเขากลายเป็นสิ่งที่บอกเป็นนัยและเป็นแบบอัตโนมัติ (บ่อยครั้งที่มีคุณค่าต่อนักพัฒนา) นั่นไม่ได้พูดถึงสถานะที่ซ่อนเร้นเช่น vptrs และอื่น ๆ ซึ่งฟังก์ชั่นดังกล่าวจะผลักไสไล่ส่ง หากf1เป็นเจ้าของพอยน์เตอร์และf2ตื้นคัดลอกพวกเขาในบริบทชั่วคราวบางอย่างแล้วมันไม่มีปัญหาถ้าเราไม่พยายามที่จะฟรีพอยน์เตอร์ที่เป็นเจ้าของเป็นครั้งที่สอง ด้วย C ++ นั่นคือสิ่งที่คอมไพเลอร์จะต้องการทำโดยอัตโนมัติ

และนั่นจะยิ่งใหญ่กว่าถ้าโดยทั่วไปใน C " ถ้า Foo เป็นเจ้าของพอยน์เตอร์" เนื่องจาก explicitness ที่จำเป็นในการจัดการทรัพยากรมักจะทำให้สิ่งที่ยากต่อการมองข้ามในขณะที่ใน C ++ เราสามารถทำให้ UDT ไม่เป็นเรื่องเล็กน้อย ที่สร้างขึ้น / ทำลายได้โดยเพียงทำให้มันเก็บตัวแปรสมาชิกใด ๆ ที่ไม่สามารถสร้างขึ้น / ทำลายได้เล็กน้อย (ในทางที่เป็นประโยชน์โดยทั่วไปมากอีกครั้ง แต่ไม่ใช่ถ้าเราถูกล่อลวงให้ใช้ฟังก์ชั่นเช่นmemcpyหรือrealloc)

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

ที่จริงแล้วสิ่งที่ดึงดูดความสนใจมากที่สุดสำหรับฉันของ C อย่างไรก็ตามโดยเฉพาะอย่างยิ่งกับวิธีการที่เกี่ยวข้องกับการทำงานร่วมกันของภาษา มันจะยากยิ่งกว่าที่จะทำบางสิ่งบางอย่างเช่น FFI ของ C # เพื่อทำความเข้าใจกับระบบแบบเต็มรูปแบบและคุณสมบัติภาษาของ C ++ ลงไปที่ตัวสร้าง, destructors, ข้อยกเว้น, ฟังก์ชันเสมือน, การโอเวอร์โหลดของฟังก์ชัน / วิธี การสืบทอด ฯลฯ ด้วย C มันเป็นภาษาที่ค่อนข้างมืดมนซึ่งค่อนข้างเป็นมาตรฐานเท่าที่ API ในรูปแบบที่ภาษาต่าง ๆ สามารถนำเข้าโดยตรงผ่าน FFIs หรือโดยอ้อมผ่านฟังก์ชันการส่งออก C API บางรูปแบบในรูปแบบที่ต้องการ (เช่น Java Native Interface ) และนั่นคือสิ่งที่ฉันส่วนใหญ่ไม่มีทางเลือกนอกจากต้องใช้ C เนื่องจากความสามารถในการทำงานร่วมกันของภาษานั้นเป็นข้อกำหนดที่ใช้งานได้จริงในกรณีของเรา

แต่คุณรู้ไหมว่าฉันเป็นนักปฏิบัตินิยม (หรืออย่างน้อยก็พยายามเป็น) ถ้า C เป็นภาษาที่หยาบคายและโหดร้ายผิดพลาดได้ง่ายน่ารังเกียจเพื่อนร่วมงาน C ++ บางคนของฉันอ้างว่ามันเป็น (และฉันจะนับตัวเองเป็นผู้ที่ชื่นชอบ C ++ ยกเว้นว่าอย่างใดก็ตามมันไม่ได้นำความเกลียดชัง C มาด้วย) ในทางตรงกันข้ามมันมีผลตรงกันข้ามกับฉันที่ทำให้ฉันซาบซึ้งทั้งสองภาษาดีกว่าในแง่ของตัวเองและความแตกต่าง) แล้วฉันก็คาดหวังว่าจะปรากฏในโลกแห่งความจริงในรูปแบบของ buggiest และ leakiest และ มีการเขียนผลิตภัณฑ์และห้องสมุดที่ไม่น่าเชื่อถือใน C. และฉันไม่พบสิ่งนั้น ฉันชอบ Linux, ฉันชอบ Apache, Lua, zlib ฉันพบว่า OpenGL สามารถทนต่อความต้องการฮาร์ดแวร์แบบขยับได้เช่น Gimp, libpng, Cairo เป็นต้น อย่างน้อยสิ่งใดก็ตามที่ภาษาโพสท่าดูเหมือนจะไม่เป็นอุปสรรคต่อการเขียนห้องสมุดและผลิตภัณฑ์เจ๋ง ๆ ในมือที่มีความสามารถและนั่นคือทั้งหมดที่ฉันสนใจดังนั้นฉันจึงไม่เคยเป็นคนที่สนใจหลงใหลมากที่สุด สงครามภาษายกเว้นที่จะดึงดูดความสนใจในทางปฏิบัติและพูดว่า "เฮ้มีสิ่งที่น่าสนใจอยู่ที่นั่นเรามาเรียนรู้วิธีที่พวกเขาสร้างมันขึ้นมาและอาจจะมีบทเรียนที่น่าสนใจไม่เฉพาะเจาะจงกับธรรมชาติของภาษา ภาษาใดก็ตามที่เราใช้ " :-D


2
memcpy(&f2, f1, sizeof f2);นอกจากนี้ยังมี "ขุมนรกครองความเสียหาย" ใน C ถ้าFooมีตัวชี้เป็นเจ้าของใด ๆ หรือยิ่งเลวร้ายลงในขณะที่คุณยังขาดเครื่องมือในการจัดการกับที่ ดังนั้นผู้คนที่เขียนภาษา C จะไม่ทำสิ่งนี้มากนัก
Caleth

@Caleth บางสิ่งที่ทำให้ง่ายขึ้นแม้กับการเป็นเจ้าของพอยน์เตอร์ก็คือการปลดปล่อยพอยน์เตอร์ที่ชัดเจนดังนั้นมันจึงกลายเป็นสำเนาตื้น ๆ ได้อย่างมีประสิทธิภาพในกรณีดังกล่าวโดยมีเพียงที่เดียวที่ยังคงปลดปล่อยหน่วยความจำดั้งเดิม การออกแบบ) ในขณะที่การมีส่วนร่วมของ destructors ทั้งสองFooกรณีอาจต้องการทำลายอาเรย์แบบไดนามิกหรือเวกเตอร์หรือบางสิ่งบางอย่างกับเอฟเฟกต์นี้ ฉันมักจะพบกรณีแปลกประหลาดบางอย่างที่เป็นประโยชน์ในการสามารถเขียนโครงสร้างข้อมูลบางอย่างเพื่อพึ่งพาความจริงที่ว่าการทำลายล้างนั้นชัดเจนมากกว่าที่จะบอกเป็นนัย
Dragon Energy

@Caleth เป็นที่ยอมรับว่าเป็นสิ่งที่ขี้เกียจในส่วนของฉันเพราะถ้าFooมีพอยน์เตอร์เป็นเจ้าของเราสามารถให้สำเนาที่ถูกต้อง / ย้าย ctor, dtor, ใช้ความหมายของค่า ฯลฯ และมีรหัสที่สมบูรณ์และปลอดภัยยิ่งขึ้น แต่บางครั้งฉันพบว่าตัวเองเข้าถึง C ในกรณีที่ฉันต้องการสรุปโครงสร้างข้อมูลหรือตัวจัดสรรในระดับบิตและไบต์ที่เป็นเนื้อเดียวกันโดยมีสมมติฐานบางอย่างที่ฉันสามารถทำได้ในประเภทที่มีแนวโน้มว่าจะง่ายขึ้นในกรณีที่แคบ เล็กน้อยโดยสมมติฐานดังกล่าวฉันรู้สึกมั่นใจมากขึ้นที่จะทำใน C.
Dragon Energy

@Caleth ในกรณีของฉันมีบางครั้งที่สำคัญบางส่วนของสถาปัตยกรรมที่ฉันพบว่าไม่มีประโยชน์ที่จะมองสิ่งต่าง ๆ มากกว่าบิตและไบต์ในหน่วยความจำเพื่อจัดเรียงและเข้าถึง (และโดยทั่วไปกรณีเหล่านั้นไม่เกี่ยวข้องกับอะไรนอกจาก POD) นี่เป็นกรณีพิเศษไม่กี่อย่างที่ฉันยังคงชอบอยู่ถ้าคุณจินตนาการว่าตัวจัดสรรหน่วยความจำไม่มีอะไรจะทำงานได้นอกจากบิตและไบต์ตัวชี้โมฆะสิ่งต่าง ๆ แบบนี้โดยมุ่งเน้นการจัดเรียงและรวมกำไร และการแจกบิตและไบต์และในกรณีพิเศษเหล่านั้นฉันพบว่า C มีอุปสรรคน้อยกว่า C ++
Dragon Energy

อีกกรณีที่บางครั้งที่ฉันไปถึง C คือกรณีที่รหัสอาจเป็นจริงมากขึ้นและนำมาใช้ซ้ำได้โดยมีบทคัดย่อน้อยลงและมุ่งเน้นที่ดั้งเดิมเช่นAPI void filter_image(byte* pixels, int w, int h);เป็นตัวอย่างง่ายๆเมื่อเทียบกับชอบAPI void filter_image(ImageInterface& img);(ซึ่งจะจับคู่รหัสของเรากับอินเตอร์เฟซภาพดังกล่าว การบังคับใช้แคบลง) ในกรณีเช่นนี้บางครั้งฉันเพิ่งใช้ฟังก์ชั่นดังกล่าวใน C เนื่องจากมีน้อยที่จะได้รับใน C ++ และลดความน่าจะเป็นที่รหัสดังกล่าวจะต้องมีการเปลี่ยนแปลงในอนาคต
Dragon Energy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.