Objective-C แตกต่างจาก C ++ อย่างไร [ปิด]


171

อะไรคือความแตกต่างที่สำคัญระหว่าง Objective-C และ C ++ ในแง่ของไวยากรณ์, คุณสมบัติ, กระบวนทัศน์, กรอบงานและห้องสมุด?

* สำคัญ: เป้าหมายของฉันคือไม่เริ่มสงครามการแสดงระหว่างสองภาษา ฉันแค่ต้องการข้อเท็จจริงที่ยากจริง ในความเป็นจริงคำถามของฉันไม่เกี่ยวข้องกับประสิทธิภาพ! โปรดให้แหล่งที่มาสำหรับสิ่งที่อาจดูเหมือนเป็นความคิดเห็น


2
คู่มือนี้ให้การเปรียบเทียบที่ดีที่สุดที่ฉันเคยเห็น
LiraNuna

@Oskar Kjellin: คำตอบของ Mac และ LiraNuna นั้นเป็นคำตอบที่ยอดเยี่ยม ฉันไม่สามารถตัดสินใจได้อย่างเด็ดขาดว่าอันไหนดีที่สุดเพราะทั้งคู่เติมเต็มซึ่งกันและกันตอบคำถาม
Alerty

@ Alyty ดีฉันรู้ (สะดุดกับที่ค่อนข้างบ่อยตัวเอง) บางทีอาจจะทำเครื่องหมายด้านบนว่าตอบซึ่งเป็นสิ่งที่ฉันทำเมื่อไม่สามารถตัดสินใจ ฉันไม่ชอบเมื่อมีคำถามที่ไม่ได้ทำเครื่องหมายว่าตอบเมื่อพวกเขาเป็น :(
Oskar Kjellin

1
ใส่ลิงค์ไปยังคำตอบที่สองในครั้งแรกและรอง / ในทางกลับกัน
ลีเทย์เลอร์

คำตอบ:


185

รายการสั้น ๆ บางส่วนของความแตกต่างที่สำคัญ:

  • C ++ อนุญาตการสืบทอดหลายอัน Objective-C ไม่รองรับ
  • ซึ่งแตกต่างจาก C ++, Objective-C อนุญาตให้ตั้งชื่อพารามิเตอร์เมธอดและเมธอดลายเซ็นต์จะรวมเฉพาะชื่อและประเภทของพารามิเตอร์และประเภทส่งคืน (ดูที่ความคิดเห็นของ bbum และ Chuck ด้านล่าง) ในการเปรียบเทียบลายเซ็นฟังก์ชันสมาชิก C ++ มีชื่อฟังก์ชั่นเช่นเดียวกับประเภทของพารามิเตอร์ / ผลตอบแทน (ไม่มีชื่อ)
  • C ++ ใช้bool, trueและfalse, ใช้ Objective-C BOOL, และYESNO
  • C ++ ใช้void*และnullptrวัตถุประสงค์-C ชอบและidnil
  • Objective-C ใช้ "selectors" (ซึ่งมีประเภทSEL) เป็นเทียบเท่าโดยประมาณกับตัวชี้ฟังก์ชั่น
  • Objective-C ใช้กระบวนทัศน์การส่งข้อความ (a la Smalltalk) ซึ่งคุณสามารถส่ง "ข้อความ" ไปยังวัตถุผ่านเมธอด / ตัวเลือก
  • วัตถุประสงค์ -C จะช่วยให้คุณส่งข้อความอย่างมีความสุขnilซึ่งแตกต่างจาก C ++ ซึ่งจะผิดพลาดหากคุณพยายามเรียกฟังก์ชันสมาชิกของnullptr
  • Objective-C อนุญาตให้ส่งข้อมูลแบบไดนามิกอนุญาตให้ชั้นตอบสนองต่อข้อความที่จะได้รับการพิจารณาที่รันไทม์ซึ่งแตกต่างจาก C ++ ที่วัตถุวิธีการที่ถูกเรียกเมื่อต้องเป็นที่รู้จักในเวลารวบรวม (ดูความคิดเห็นของ wilhelmtell ด้านล่าง) เรื่องนี้เกี่ยวข้องกับประเด็นก่อนหน้า
  • Objective-C ช่วยให้การเข้าถึงอัตโนมัติสำหรับตัวแปรสมาชิกใช้ "คุณสมบัติ"
  • Objective-C อนุญาตให้กำหนดselfและอนุญาตให้ initialisers คลาส (คล้ายกับ constructors) เพื่อส่งคืนคลาสที่แตกต่างอย่างสิ้นเชิงถ้าต้องการ ตรงกันข้ามกับ C ++ โดยที่หากคุณสร้างอินสแตนซ์ใหม่ของคลาส (ไม่ว่าจะโดยปริยายบนสแต็กหรือผ่านอย่างชัดเจนnew) จะรับประกันว่าเป็นประเภทที่คุณระบุไว้ตั้งแต่แรก
  • ในทำนองเดียวกันใน Objective-C คลาสอื่นอาจเปลี่ยนคลาสเป้าหมายที่รันไทม์เพื่อสกัดกั้นการเรียกเมธอด
  • วัตถุประสงค์ -C ขาดคุณสมบัติเนมสเปซของ C ++
  • วัตถุประสงค์ -C ขาดการอ้างอิงเทียบเท่ากับ C ++
  • Objective-C ไม่มีเทมเพลตเลือกใช้ (ตัวอย่าง) เพื่ออนุญาตการพิมพ์ที่ไม่ดีในคอนเทนเนอร์
  • Objective-C ไม่อนุญาตให้ใช้การโอเวอร์โหลดวิธีโดยนัย แต่ C ++ ทำได้ นั่นคือใน C ++ int foo (void)และint foo (int)กำหนดเกินนัยของวิธีการfooแต่เพื่อให้บรรลุเดียวกันใน Objective-C ต้องเกินอย่างชัดเจนและ- (int) foo - (int) foo:(int) intParamนี่เป็นเพราะพารามิเตอร์ที่มีชื่อของ Objective-C นั้นมีหน้าที่เทียบเท่ากับชื่อของ c ++
  • วัตถุประสงค์ -C จะอนุญาตให้เมธอดและตัวแปรแบ่งปันชื่อเดียวกันอย่างมีความสุขซึ่งแตกต่างจาก C ++ ซึ่งโดยทั่วไปแล้วจะมีความเหมาะสม ฉันคิดว่านี่เป็นสิ่งที่ต้องทำกับ Objective-C โดยใช้ selectors แทนที่จะเป็นตัวชี้ฟังก์ชั่นดังนั้นชื่อเมธอดที่ไม่มี "value"
  • Objective-C ไม่อนุญาตให้วัตถุถูกสร้างขึ้นบนสแต็ก - วัตถุทั้งหมดจะต้องได้รับการจัดสรรจากฮีป (อย่างชัดเจนด้วยallocข้อความหรือโดยนัยในวิธีการของโรงงานที่เหมาะสม)
  • เช่น C ++, Objective-C มีทั้ง structs และคลาส อย่างไรก็ตามใน C ++ พวกเขาได้รับการปฏิบัติเหมือนกันเกือบทั้งหมดใน Objective-C พวกเขาจะได้รับการปฏิบัติต่างกันอย่างดุเดือด - คุณสามารถสร้าง structs บนสแต็กได้

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

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

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

แก้ไข: อัปเดตเพื่อจัดการกับจุดที่เพิ่มขึ้นในความคิดเห็นต่อไปนี้เพิ่มรายการเพิ่มเติมอีกสองสามรายการ


8
รายการที่มีคุณค่า; หนึ่งการแก้ไข พวกเขาไม่ได้ "ตั้งชื่อพารามิเตอร์" แต่ "พารามิเตอร์ interleaved" การตั้งชื่อและ "การโต้แย้งคำหลัก" นำไปสู่ความสับสนของการคิดว่าอาจมีการตัดบางส่วนของชื่อวิธี มันไม่สามารถ
bbum

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

9
@wilhelmtell: คอมไพเลอร์ C ++ รู้จักซูเปอร์คลาสในเวลารวบรวมเท่านั้น ณ รันไทม์คลาสจริงอาจเป็นผู้สืบทอดใด ๆ นี่เป็นรูปแบบของการจัดส่งแบบไดนามิก แต่ไม่เหมือนกับที่ใช้ใน Objective C เพียงระวังข้อตกลงทางเทคนิคเหล่านั้น!
Norman Ramsey

5
+1 รายการดี อย่างไรก็ตาม Objective-C ยังใช้void*และNULLไม่ได้มีไว้สำหรับวัตถุ คุณสามารถใช้ตัวชี้รูปแบบ C ใด ๆ ใน Obj-C และการเรียก API จำนวนมากผ่านหรือส่งคืนค่าโดยการอ้างอิงซึ่งในกรณีNULLนี้จะใช้บ่อย
Quinn Taylor

3
@wilhelmtell - ฉันไม่รู้อะไรเลยเกี่ยวกับวัตถุประสงค์ -C แต่ใน C ++ คุณสามารถมีคลาสที่แตกต่างกันตอบสนองต่อการเรียกใช้ฟังก์ชันได้ แต่คุณต้องมีบางอย่างเช่นพอยน์เตอร์พอยน์เตอร์ถึงคลาสพื้นฐานและจากนั้นชั้นเรียน ACTUAL ที่ "ห้อย" ออกไปจากมัน ในขณะที่ทุกคลาสนั้นจำเป็นต้องมีคลาสย่อยวิธีการเรียกจะจะเรียกวิธีการที่แตกต่างกันขึ้นอยู่กับชั้นเรียนในเวลาทำงาน
Kevin Anderson

33

ในขณะที่พวกเขาทั้งสองรูตใน C พวกเขาเป็นสองภาษาที่แตกต่างกันอย่างสมบูรณ์

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

เกี่ยวกับไลบรารีคุณสามารถใช้ไลบรารี C ธรรมดาในทั้งสองภาษา - แต่ไลบรารีดั้งเดิมมีความแตกต่างอย่างสิ้นเชิง

ที่น่าสนใจคือคุณสามารถผสมทั้งสองภาษา (มีข้อ จำกัด บางอย่าง) ผลที่ได้คือเรียกว่าObjective-C ++


ลิงก์ที่อัพเดท: Objective-C ++
IcyIcicle


6

ปิดส่วนหัวของฉัน:

  1. ลักษณะ - Obj-C เป็นแบบไดนามิกโดยทั่วไป C ++ จะเป็นแบบคงที่
  2. แม้ว่าพวกเขาจะเป็นทั้ง OOP แต่ฉันมั่นใจว่าโซลูชันจะแตกต่างกัน
  3. โมเดลวัตถุที่แตกต่าง (C ++ ถูก จำกัด โดยระบบประเภทเวลาคอมไพล์)

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

แต่ละคนมีจุดแข็ง


5

ดังที่คนอื่น ๆ ได้กล่าวไว้ว่า Objective-C นั้นมีพลวัตมากขึ้นในแง่ของความคิดของวัตถุเทียบกับขอบเขตที่ค่อนข้างคงที่ของ C ++

Objective-C อยู่ในสายเลือด Smalltalk ของภาษาเชิงวัตถุมีแนวคิดของวัตถุที่คล้ายกับภาษา Java, Python และ "มาตรฐาน" อื่น ๆ , ภาษาที่ไม่ใช่เชิงวัตถุ C ++ การกระจายแบบไดนามิกจำนวนมากไม่มีผู้ให้บริการมากเกินไปส่งข้อความไปรอบ ๆ

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


4

Objective-C เป็น superset ที่สมบูรณ์แบบมากขึ้นของ C ใน C และ Objective-C การส่อให้เห็นโดยปริยายจากvoid*ไปยังตัวชี้ struct ได้รับอนุญาต

Foo* bar = malloc(sizeof(Foo));

C ++ จะไม่คอมไพล์ยกเว้นว่าvoidตัวชี้ถูกส่งออกมาอย่างชัดเจน:

Foo* bar = (Foo*)malloc(sizeof(Foo));

ความเกี่ยวข้องของสิ่งนี้กับการเขียนโปรแกรมทุกวันเป็นศูนย์เพียงแค่เรื่องสนุก ๆ


ตัวอย่างที่สองไม่ใช่รหัส C ++ มันเป็นรหัส C ที่ทำให้คุณมีข้อผิดพลาดเมื่อคุณพยายามคอมไพล์ด้วย C ++ คอมไพเลอร์ ถ้าคุณต้องการ C ++ เก่าใกล้เคียงกับต้นฉบับคุณFoo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo));อาจจะเขียนแล้วอาจจะใช้ตัวสร้างแบบ inplace .. แต่ ณ วันนี้มัน Modern C ++ เหมือนauto bar = new Foo(constructorArg);จริงคุณไม่ต้องการ malloc และ callic อย่างใดอย่างหนึ่งคุณอาจใช้std::vector::reserveและstd::vector::emplace_mack
xakepp35

3

Obj-C มีความสามารถแบบไดนามิกมากขึ้นในภาษาของตัวเองในขณะที่ C ++ จะเน้นที่ความสามารถในการรวบรวมเวลาที่มีความสามารถแบบไดนามิกบางอย่าง

ใน C + + Parametric polymorphism ถูกตรวจสอบ ณ เวลาคอมไพล์ขณะที่ใน Obj-C, polamorphism ที่แปรผันนั้นสามารถทำได้ผ่านการกระจายแบบไดนามิกและไม่ได้ตรวจสอบ ณ เวลาที่คอมไพล์

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

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


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

1
จริงมีข้อเสียระหว่างต้นทุนรันไทม์เทียบกับเวลารวบรวม อย่างไรก็ตามเวลาในการรวบรวมนั้นไม่ได้เป็นเรื่องเล็กน้อยเสมอไป การใช้ metaprogramming จำนวนมากและไลบรารี EDSLs ใน C ++ (เช่น Boost.Spirit) อาจมีผลอย่างมากต่อเวลาในการคอมไพล์ขณะที่สร้างโค้ดที่รวดเร็วมากในขณะทำงาน
Paul Fultz II

1
แน่นอนว่าฉันกำลังขยายความสัมพันธ์กับ POV ของโค้ดเบสที่ง่ายกว่า ... ด้วยโค้ดเบสที่ซับซ้อนมากการคอมไพล์ซ้ำเพื่อทดสอบการเปลี่ยนแปลงเล็ก ๆ อาจทำให้การพัฒนาน่าเบื่อมากซึ่งไม่ใช่เรื่องเล็กน้อย แต่นี่คือสิ่งที่เราสามารถเปรียบเทียบระหว่างทั้งสองได้จริงหรือ ไลบรารีดังกล่าวสามารถพึ่งพาการรวบรวมเวลา C ++ ได้หรือไม่สามารถนำไปใช้ใหม่ใน Objective-C และแสดงเพื่อรวบรวมได้เร็วขึ้น? คือคำสั่ง "Obj-C นั้นเร็วกว่าในการคอมไพล์มากกว่า C ++ หรือไม่" อ้างถึงรหัสฐานที่เทียบเท่าซึ่งการวัดความเร็วแบบจำลองสามารถวัดได้หรือไม่? มิฉะนั้นเราจะเปรียบเทียบเวลาที่ใช้ในการปลูกแอปเปิ้ลกับส้ม
underscore_d
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.