Objective-C khác với C ++ như thế nào? [đóng cửa]


171

Sự khác biệt chính giữa Objective-C và C ++ về cú pháp, tính năng, mô hình, khung và thư viện là gì?

* Quan trọng: Mục tiêu của tôi là không bắt đầu cuộc chiến hiệu suất giữa hai ngôn ngữ. Tôi chỉ muốn sự thật khó khăn. Trong thực tế, câu hỏi của tôi không liên quan đến hiệu suất! Vui lòng cung cấp nguồn cho bất cứ điều gì có vẻ chủ quan.


2
Hướng dẫn này đưa ra sự so sánh tốt nhất mà tôi đã thấy.
LiraNuna

@Oskar Kjellin: Câu trả lời của Mac và LiraNuna đều là những câu trả lời xuất sắc. Tôi không thể quyết định một cách khách quan cái nào là tốt nhất bởi vì cả hai đều bổ sung cho nhau câu trả lời.
Alerty

@Alerty tôi cũng biết (vấp vào đó khá thường xuyên). Có lẽ chỉ cần đánh dấu đầu trang là trả lời, đó là những gì tôi làm khi không thể quyết định. Tôi không thích khi có những câu hỏi không được đánh dấu là đã trả lời khi chúng là :(
Oskar Kjellin

1
Đặt một liên kết đến câu trả lời thứ hai trong câu đầu tiên và ngược lại
Lee Taylor

Câu trả lời:


185

Danh sách ngắn của một số khác biệt chính:

  • C ++ cho phép nhiều kế thừa, Objective-C thì không.
  • Không giống như C ++, Objective-C cho phép đặt tên các tham số của phương thức và chữ ký phương thức chỉ bao gồm tên và loại của tham số và kiểu trả về (xem các bình luận của bbum và Chuck bên dưới). Để so sánh, chữ ký hàm thành viên C ++ chứa tên hàm cũng như chỉ các loại tham số / return (không có tên của chúng).
  • C ++ sử dụng bool, truefalse, sử dụng Objective-C BOOL, YESNO.
  • C ++ sử dụng void*nullptr, Objective-C thích idnil.
  • Objective-C sử dụng "bộ chọn" (có loại SEL) tương đương với con trỏ hàm.
  • Objective-C sử dụng mô hình nhắn tin (a la Smalltalk) nơi bạn có thể gửi "tin nhắn" đến các đối tượng thông qua các phương thức / bộ chọn.
  • Objective-C sẽ vui vẻ cho phép bạn gửi tin nhắn đến nil, không giống như C ++ sẽ bị sập nếu bạn cố gọi một hàm thành viên củanullptr
  • Objective-C cho phép gửi động, cho phép lớp trả lời tin nhắn được xác định trong thời gian chạy, không giống như C ++ trong đó đối tượng được gọi theo phương thức phải được biết vào thời gian biên dịch (xem bình luận của wilmustell bên dưới). Điều này có liên quan đến điểm trước.
  • Objective-C cho phép tự động tạo ra các bộ truy cập cho các biến thành viên bằng cách sử dụng "thuộc tính".
  • Objective-C cho phép gán selfvà cho phép các trình khởi tạo lớp (tương tự như các hàm tạo) trả về một lớp hoàn toàn khác nếu muốn. Tương phản với C ++, trong đó nếu bạn tạo một thể hiện mới của một lớp (mặc nhiên trên ngăn xếp hoặc thông qua rõ ràng new) thì nó được đảm bảo là loại bạn đã chỉ định ban đầu.
  • Tương tự, trong Objective-C, các lớp khác cũng có thể thay đổi động một lớp đích trong thời gian chạy để chặn các cuộc gọi phương thức.
  • Objective-C thiếu tính năng không gian tên của C ++.
  • Objective-C thiếu tương đương với các tham chiếu C ++.
  • Objective-C thiếu các mẫu, thay vào đó, ưu tiên (ví dụ) để cho phép gõ yếu trong các thùng chứa.
  • Objective-C không cho phép nạp chồng phương thức ngầm định, nhưng C ++ thì có. Đó là, trong C ++ int foo (void)int foo (int)định nghĩa một quá tải ngầm định của phương thức foo, nhưng để đạt được điều tương tự trong Objective-C đòi hỏi phải quá tải rõ ràng - (int) foo- (int) foo:(int) intParam. Điều này là do các tham số được đặt tên của Objective-C có chức năng tương đương với việc xáo trộn tên của C ++.
  • Objective-C sẽ vui vẻ cho phép một phương thức và một biến chia sẻ cùng tên, không giống như C ++ thường có sự phù hợp. Tôi tưởng tượng đây là một cái gì đó để làm với Objective-C bằng cách sử dụng các bộ chọn thay vì các con trỏ hàm và do đó tên phương thức không thực sự có "giá trị".
  • Objective-C không cho phép các đối tượng được tạo trên ngăn xếp - tất cả các đối tượng phải được phân bổ từ heap (rõ ràng bằng một allocthông báo hoặc ẩn trong một phương thức xuất xưởng phù hợp).
  • Giống như C ++, Objective-C có cả cấu trúc và lớp. Tuy nhiên, trong C ++, chúng được xử lý gần như giống hệt nhau, trong Objective-C, chúng được xử lý khác nhau - ví dụ, bạn có thể tạo các cấu trúc trên ngăn xếp.

Theo tôi, có lẽ sự khác biệt lớn nhất là cú pháp. Về cơ bản, bạn có thể đạt được những điều tương tự trong cả hai ngôn ngữ, nhưng theo tôi, cú pháp C ++ đơn giản hơn trong khi một số tính năng của Objective-C làm cho một số tác vụ nhất định (như thiết kế GUI) dễ dàng hơn nhờ gửi động.

Có lẽ còn nhiều điều khác nữa mà tôi đã bỏ lỡ, tôi sẽ cập nhật với bất kỳ điều gì khác mà tôi nghĩ đến. Ngoài ra, rất có thể giới thiệu hướng dẫn LiraNuna chỉ cho bạn. Ngẫu nhiên, một trang web quan tâm khác có thể là điều này .

Tôi cũng nên chỉ ra rằng bản thân tôi mới bắt đầu học Objective-C, và rất nhiều điều ở trên có thể không hoàn toàn chính xác hoặc hoàn chỉnh - Tôi xin lỗi nếu đó là trường hợp và hoan nghênh các đề xuất cải tiến.

EDIT: được cập nhật để giải quyết các điểm nêu ra trong các bình luận sau đây, thêm một vài mục vào danh sách.


8
Danh sách kế thừa; một điều chỉnh. Chúng không phải là "tham số được đặt tên", mà là "tham số xen kẽ". Được đặt tên và "đối số từ khóa" dẫn đến nhầm lẫn khi nghĩ rằng một số tập hợp con của tên phương thức có thể bị bỏ qua. Nó không thể.
bbum

7
Bạn đã quên tranh thủ sự khác biệt quan trọng nhất: Object-C sử dụng công văn động, trong khi C ++ sử dụng công văn tĩnh. Nói cách khác, mã được biên dịch bởi trình biên dịch Objective-C sẽ có lớp chịu trách nhiệm trả lời một thông báo được xác định khi chạy; mã được biên dịch bởi trình biên dịch C ++ có thông tin này được tính toán và biên dịch tại compXLime.
wilmustell 15/03/2016

9
@wilmustell: Trình biên dịch C ++ chỉ biết siêu lớp tại thời gian biên dịch. Trong thời gian chạy, lớp thực tế có thể là bất kỳ hậu duệ. Đây cũng là một hình thức của công văn động, nhưng không phải là hình thức giống như được sử dụng trong Mục tiêu C. Chỉ cần cẩn thận với các thuật ngữ kỹ thuật đó!
Norman Ramsey

5
+1 Danh sách tốt. Tuy nhiên, Objective-C cũng sử dụng void*NULL, không chỉ cho các đối tượng. Bạn có thể sử dụng bất kỳ con trỏ kiểu C nào trong Obj-C và nhiều lệnh gọi API thực sự chuyển hoặc trả về giá trị theo tham chiếu, trong trường hợp NULLnày thường được sử dụng.
Quinn Taylor

3
@wilmustell - Tôi không biết bất cứ điều gì về object-C, nhưng trong C ++, bạn có thể có một lớp khác đáp ứng một lệnh gọi hàm, nhưng bạn cần phải có một thứ giống như một con trỏ tới một lớp cơ sở, và sau đó là các lớp THỰC TẾ đó là "treo" ra khỏi nó. Trong khi tất cả các lớp cần phải có các lớp con, một phương thức gọi SILL gọi các phương thức khác nhau tùy thuộc vào lớp, vào thời gian chạy.
Kevin Anderson

33

Trong khi cả hai đều bắt nguồn từ C, chúng là hai ngôn ngữ hoàn toàn khác nhau.

Một điểm khác biệt lớn là Objective-C tập trung vào các quyết định thời gian chạy để gửi đi và phụ thuộc rất nhiều vào thư viện thời gian chạy của nó để xử lý tính kế thừa và đa hình, trong khi trong C ++, trọng tâm thường nằm ở các quyết định tĩnh, biên dịch.

Về thư viện, bạn có thể sử dụng thư viện C đơn giản trong cả hai ngôn ngữ - nhưng thư viện gốc của chúng hoàn toàn khác nhau.

Điều đáng quan tâm là bạn có thể kết hợp cả hai ngôn ngữ (với một số hạn chế). Kết quả được gọi là Objective-C ++ .


liên kết được cập nhật: Objective-C ++
IcyIcicle

6

Chúng hoàn toàn khác nhau. Mục tiêu C có nhiều điểm chung với Smalltalk hơn là với C ++ (tốt, ngoại trừ cú pháp, thực sự).


6

Off đỉnh đầu của tôi:

  1. Kiểu dáng - Obj-C là động, C ++ thường tĩnh
  2. Mặc dù cả hai đều là OOP, tôi chắc chắn các giải pháp sẽ khác nhau.
  3. Mô hình đối tượng khác nhau (C ++ bị hạn chế bởi hệ thống kiểu biên dịch thời gian).

Đối với tôi, sự khác biệt lớn nhất là hệ thống mô hình. Obj-C cho phép bạn nhắn tin và hướng nội, nhưng C ++ có các mẫu cực kỳ mạnh mẽ.

Mỗi người có điểm mạnh riêng.


5

Như những người khác đã nói, Objective-C năng động hơn nhiều về cách nó nghĩ về các đối tượng so với lĩnh vực khá tĩnh của C ++.

Objective-C, thuộc dòng ngôn ngữ Smalltalk của các ngôn ngữ hướng đối tượng, có khái niệm về các đối tượng rất giống với ngôn ngữ của Java, Python và các ngôn ngữ hướng đối tượng "tiêu chuẩn", không phải C ++ khác. Rất nhiều công văn năng động, không có nhà điều hành quá tải, gửi tin nhắn xung quanh.

C ++ là động vật kỳ lạ của riêng nó; nó chủ yếu bỏ qua phần Smalltalk của cây gia đình. Theo một số cách, nó có một hệ thống mô-đun tốt với sự hỗ trợ cho sự kế thừa tình cờ có thể được sử dụng để lập trình hướng đối tượng. Mọi thứ tĩnh hơn nhiều (ví dụ, các phương thức overridable không phải là mặc định).


4

Objective-C là một superset hoàn hảo hơn của C. Trong C và Objective-C, việc truyền ẩn từ void*con trỏ cấu trúc được cho phép.

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

C ++ sẽ không biên dịch trừ khi voidcon trỏ được truyền rõ ràng:

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

Sự liên quan của điều này với lập trình hàng ngày là bằng không, chỉ là một sự thật nhỏ nhặt thú vị.


Ví dụ thứ hai không phải là mã C ++. Đó là mã C đã báo lỗi cho bạn khi bạn cố biên dịch nó với trình biên dịch C ++. Nếu bạn muốn C ++ cũ gần giống với bản gốc, bạn sẽ viết Foo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo));thì có thể sử dụng hàm tạo tại chỗ .. Nhưng cho đến ngày nay, C ++ hiện đại của nó giống như auto bar = new Foo(constructorArg);thực sự bạn không cần malloc, và có thể sử dụng std::vector::reserve, vàstd::vector::emplace_mack
xakepp35

3

Obj-C có khả năng năng động hơn nhiều trong ngôn ngữ, trong khi C ++ tập trung nhiều hơn vào khả năng biên dịch thời gian với một số khả năng động.

Trong, đa hình tham số C ++ được kiểm tra tại thời gian biên dịch, trong khi ở Obj-C, đa hình tham số đạt được thông qua công văn động và không được kiểm tra tại thời gian biên dịch.

Obj-C rất năng động trong tự nhiên. Bạn có thể thêm các phương thức vào một lớp trong thời gian chạy. Ngoài ra, nó có nội tâm vào thời gian chạy để xem xét các lớp. Trong C ++, định nghĩa của lớp không thể thay đổi và tất cả nội tâm phải được thực hiện tại thời gian biên dịch. Mặc dù, bản chất động của Obj-C có thể đạt được trong C ++ bằng cách sử dụng bản đồ các hàm (hoặc một cái gì đó tương tự), nhưng nó vẫn dài dòng hơn so với Obj-C.

Trong C ++, có rất nhiều kiểm tra có thể được thực hiện tại thời điểm biên dịch. Ví dụ, bằng cách sử dụng một loại biến thể (như liên minh), trình biên dịch có thể thực thi rằng tất cả các trường hợp được viết hoặc xử lý. Vì vậy, bạn đừng quên xử lý các trường hợp cạnh của một vấn đề. Tuy nhiên, tất cả các kiểm tra này có giá khi biên dịch. Obj-C biên dịch nhanh hơn nhiều so với C ++.


3
Nếu bạn sẽ nói về giá cả, hãy công bằng! Ngược lại, Obj-C chậm hơn nhiều trong việc giải quyết các cuộc gọi phương thức động khi chạy so với C ++. Và tôi cho rằng tốc độ biên dịch là một sự tầm thường tương đối so với tốc độ thời gian chạy. Tôi chắc chắn Obj-C mang lại nhiều lợi ích nhờ công văn năng động hơn, nhưng có một sự đánh đổi ở đó.
gạch dưới

1
Đúng, có một sự đánh đổi giữa thời gian chạy so với chi phí thời gian biên dịch. Tuy nhiên, thời gian biên dịch không phải lúc nào cũng tầm thường. Sử dụng các thư viện siêu dữ liệu và EDSLs nặng trong C ++ (chẳng hạn như Boost.Sprite) có thể có tác động mạnh mẽ đến thời gian biên dịch, trong khi tạo mã rất nhanh khi chạy.
Paul Fultz II

1
Chắc chắn, tôi đã quá đơn giản so với POV của các cơ sở mã đơn giản hơn ... Với các cơ sở mã rất phức tạp, việc biên dịch lại để kiểm tra các thay đổi nhỏ có thể khiến việc phát triển trở nên rất tẻ nhạt, không phải là chuyện nhỏ. Nhưng đây có phải là một cái gì đó chúng ta thực sự có thể so sánh giữa hai? Các thư viện như vậy, có thể phụ thuộc vào các tính năng thời gian biên dịch C ++, bằng cách nào đó được mô phỏng lại trong Objective-C & được hiển thị để biên dịch nhanh hơn không? tức là câu lệnh "Obj-C có khả năng biên dịch nhanh hơn nhiều so với C ++" đề cập đến các cơ sở mã tương đương mà có thể đo tốc độ có thể nhân rộng? Mặt khác, chúng ta so sánh thời gian trồng táo và cam.
gạch dưới
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.