2010-09-01 16 views
7

Trước hết, hãy để tôi làm rõ đầu tiên rằng những suy nghĩ dưới đây hoàn toàn là ý kiến ​​cá nhân của tôi và do kiến ​​thức hạn chế của tôi. Tôi không có ý định nói rằng C++ không phải là mát mẻ.C++ từ chế độ xem Java: Tôi phải bỏ lỡ một vài điều

Tôi đã lập trình C++ trong một năm và tôi nghĩ nó thực sự có một số tính năng thú vị. Tuy nhiên, tôi cảm thấy hơi trống rỗng và thất vọng vì tôi không thực sự học bất cứ thứ gì "thay đổi tâm trí" từ C++, từ quan điểm của một người đã từng học Java trước đây (là ngôn ngữ thứ nhất).

Theo nhiều bài đăng tôi đã đọc, mọi người thích C++ vì nó nhanh hơn. Đối với một lập trình viên như tôi, những người chưa lập trình các ứng dụng thời gian quan trọng trước đây, tôi chưa có cơ hội để đánh giá cao điều này.

Cho đến nay, những gì tôi đã học dường như với tôi là tất cả về cú pháp. Đây là cách chúng ta viết một lớp trong Java, và đây là cách viết nó trong C++. Đây là cách làm kế thừa trong Java và đó là cách làm trong C++ và vân vân. (Tôi biết, nhiều thừa kế là mát mẻ, nhưng đối với tôi, không phải là một điều thay đổi tâm trí. Tôi nghĩ rằng điều thú vị là có thể trả lời tại sao Java không/không thể hỗ trợ đa thừa kế, được cho là tổng quát hơn so với thừa kế đơn).

Bằng cách nào đó với tôi, tất cả chỉ là cú pháp và tâm trí của tôi dường như không phát triển sau khi mã hóa C++, cho đến nay. Tôi nghĩ rằng vấn đề của tôi là viết các chương trình C++ với một "Java-mind". Điều tôi thực sự muốn là, như nhiều người đã đề xuất, để thay đổi cách suy nghĩ của tôi sau khi học một ngôn ngữ mới. Tôi chưa đạt được điều đó với C++ của tôi.

Tôi cũng có thể viết một vài chương trình Python nhỏ. Tuy nhiên, tôi cảm thấy sợ phải tìm hiểu thêm về nó như với tôi, một lần nữa, nó sẽ chỉ là học một cú pháp mới, một cách mới để làm những điều khác biệt, mà không biết lý do.

Tôi dự định học C để thực sự tìm hiểu mọi thứ. Tôi nghĩ rằng nó sẽ là một ngôn ngữ khá "liên quan".

Hãy cho tôi biết suy nghĩ của bạn và vui lòng cho tôi một số lời khuyên.

PS: Btw, có một câu hỏi cụ thể trong C++ tôi muốn xác nhận. Trong C++, viết theo cách sau là không hiệu quả, nếu tôi đúng:

private A computeAndReturnA(){...} 

Thay vào đó, hãy viết nó như:

private void computeAndReturnA(A& a){...} 

như trong cách đầu tiên, các giá trị trả được sao chép (khi chúng ta gán b = tính toán ...) và giới thiệu một số sự thiếu hiệu quả? (Trong Java, tôi đoán cách thứ nhất rõ ràng về ý nghĩa và hiệu quả khi nó vượt qua mọi thứ bằng cách tham khảo)

+2

C++ và Java là cả hai ngôn ngữ Hướng đối tượng với trọng tâm nhấn mạnh vào OOP. Trong ý nghĩa đó, chúng quá giống với nó để thực sự "thay đổi tâm trí" để học cái này sau cái kia. Cả C++ và Java đều có điểm mạnh và điểm yếu tương đối. Để có một trải nghiệm "thay đổi tâm trí" thực sự, hãy học một loại ngôn ngữ hoàn toàn khác. Python (và cũng Ruby) cũng tốt, nhưng bạn có thể thử một ngôn ngữ chức năng như chương trình hoặc haskell hoặc thậm chí thử một ngôn ngữ như một prolog để có được một cái nhìn thực sự khác nhau của lập trình. Nhưng bây giờ tôi sẽ đi với Python. – MAK

+2

@ MAK: Bạn rõ ràng chưa làm đủ C++. C++ là một ngôn ngữ đa mô hình bằng nhau. Đúng là nhiều thư viện chuẩn của C++ được cung cấp ở định dạng OO, nhưng có rất nhiều thư viện không có. – Puppy

+0

@MAK: Tôi sẽ phải đồng ý với DeadMG tại đây. Chuyển dịch mô hình chuyển từ Java sang C++ là rất lớn. Sự tương đồng duy nhất giữa các ngôn ngữ là cú pháp (và đó là cố ý). Cách mọi thứ được thực hiện một cách chính xác là không giống nhau đến nỗi thật khó cho một lập trình viên Java thực sự chuyển đổi (vì chúng có xu hướng viết Java như mã trong C++). –

Trả lời

6

Bạn hoàn toàn sai, trong ngắn hạn. Thực tế là C++ cung cấp số lượng tự do HUGE so với Java.

Ví dụ: bạn có thể phân bổ các lớp học trên ngăn xếp. Java không cung cấp điều đó. Bạn có thể tính giá trị nhất định tại thời gian biên dịch. Mẫu cung cấp nhiều quyền lực hơn so với generics. Bạn có khả năng biến một thứ gì đó thành một tham chiếu hoặc một giá trị. Trong Java, tất cả các lựa chọn này được lấy ra khỏi bạn. Giống như, trong C++ bạn có thể mở rộng nhiều hơn một lớp. Bạn không bị buộc phải mở rộng Object. Làm sạch tài nguyên xác định, nếu bạn muốn. Tôi có thể tiếp tục và cứ mãi mãi.

Nếu tất cả những gì bạn làm là tìm hiểu các biến thể cú pháp, thì bạn hoàn toàn có thể sử dụng C++ theo cách có thể chấp nhận được. Tuy nhiên, C++ cung cấp hàng tá thứ mà bạn sẽ không bao giờ thấy trong Java.

Sự thật đơn giản là Java giống như một tập hợp con của C++ với một thư viện chuẩn lớn hơn, cộng với sự phản chiếu và tạo mã thời gian chạy, tôi đoán vậy.

Tôi thích C++ hơn vì Java, thẳng thắn, có đầy đủ các hạn chế tùy ý. Bạn có biết tại sao không có câu lệnh "friend" trong Java không? Bởi vì James Gosling nghĩ rằng nó đi ngược lại nguyên tắc của anh ta. Tuyệt quá. Thật tuyệt vời. Bây giờ tôi cần chia nhỏ việc triển khai của tôi thành hai lớp và phải giả vờ rằng đó là hai triển khai với đóng gói riêng biệt bởi vì anh ta nghĩ cách đây mười năm rằng nó không phải là điều đúng đắn để làm. Đó là ví dụ cá nhân của tôi về lý do tại sao Java hút rất nhiều - bạn lập trình như thế nào James Gosling nói rằng bạn nên, không phải như thế nào bạn muốn hoặc, trong nhiều trường hợp, làm thế nào bạn thực sự cần.

Ngoài ra, tôi đã xem xét PS của bạn. Đó là lý do tại sao C++ có trình biên dịch thích hợp. Thực tế là hầu như tất cả các trình biên dịch sẽ biến hình thức đầu tiên thành thứ hai cho bạn, và một số tối ưu hóa tâm uốn khác mà bạn không muốn biết về điều đó được thực hiện đằng sau hậu trường.

+2

OK, bạn có thể làm nhiều điều "thú vị" hơn với C++, nhưng nó có giúp giải quyết các vấn đề trong thế giới thực hay nó chỉ giới thiệu một mức độ phức tạp khác? – Mot

+1

Đó không phải là câu hỏi trong OP. Anh ấy muốn biết những gì trong C++ không có trong Java, và tôi đã nói với anh ấy. Bên cạnh đó, làm thế nào có thể có chính xác khả năng tương tự như Java nhưng KHÔNG giúp đỡ nhiều hơn? – Puppy

+0

@mklhmnn, C++ không giải quyết được các vấn đề trong thế giới thực. Ngoài ra việc học có thể phức tạp * nhưng tôi không nghĩ ngôn ngữ tự giới thiệu một mức độ phức tạp khác .. – liaK

2

Học C là lựa chọn tốt nhất của bạn ở đây - Nó sẽ giúp bạn xuống đến xương trần, không sử dụng suy nghĩ Java của bạn và như vậy bạn có thể có một chuyển đổi dễ dàng, đẹp hơn sang C++.

+1

Cá nhân và người khác có thể không đồng ý. Có phải đó là việc học C là một sự lãng phí thời gian (trong việc giúp bạn học C++/Nó là một ngôn ngữ phức tạp theo cách riêng của nó với cách làm riêng của nó). Nhưng nó sẽ không làm cho việc chuyển đổi sang C++ dễ dàng hơn. –

+1

C và C++ về cơ bản là tương tự. Có, C++ là ngôn ngữ riêng của nó, nhưng biết cách con trỏ và công việc như thế là một lợi thế lớn. – alternative

+0

Hiện đại C++ là một con thú khác với C. C++ hiện đại sử dụng các mẫu, RAII và những thứ khác không thực sự hiện diện trong hầu hết các ngôn ngữ lập trình khác và chắc chắn không có trong C. Chỉ vì cả con trỏ hỗ trợ C và C++ và có một nền được chia sẻ không làm cho chúng cơ bản giống nhau. Trong thực tế, tôi sẽ nói rằng điểm bắt đầu thiết kế của C++ luôn là giải quyết các vấn đề chung, tiêu chuẩn C dường như ngày càng nhiều về việc hỗ trợ những điều rất cụ thể, ví dụ: kiểu 'complex'. –

1

Nếu bạn đang cố gắng học các ngôn ngữ mới để cải thiện kỹ năng lập trình của bạn, có lẽ hãy thử và tìm hiểu điều gì đó hoàn toàn khác với cú pháp kiểu C. Có lẽ một trong những ngôn ngữ chức năng như Haskell, Scala hoặc Erlang. Điều đó sẽ cho bạn thấy các ngôn ngữ lập trình khác nhau có thể như thế nào và bạn sẽ bắt đầu nhận ra sự khác biệt tinh tế giữa Java/C++/C.

Nếu không, nếu bạn muốn giải quyết một vấn đề cụ thể, bạn có thể chọn ngôn ngữ cho điều đó. Trừ khi bạn có một cái gì đó là hiệu suất quan trọng nó có lẽ là dễ dàng hơn để dính vào các ngôn ngữ thu gom rác thải. Trừ khi bạn đang lập kế hoạch phát triển iPhone, trong trường hợp này, bạn nên chuyển sang Objective-C

+0

Cảm ơn leonm vì lời khuyên mát mẻ. –

1

Câu hỏi của bạn: C++ 0x sắp tới sẽ có ngữ nghĩa di chuyển, sẽ tăng tốc độ "trả về theo giá trị" hiệu suất của "trở lại bằng tham chiếu". Những không cần một sự thay đổi trong mã khách hàng, nhưng người ta có thể cần phải thực hiện một constructor bổ sung trong các lớp học di chuyển.

Giới thiệu về Rant: Đọc "Thiết kế C++ hiện đại: Mẫu lập trình chung và mẫu thiết kế được ứng dụng" của Andrei Alexandrescu và ngạc nhiên về mức độ C++ và Java (và suy nghĩ tương ứng) có thể khác nhau.

1

Lý do tại sao bạn có thể không cảm thấy như C++ cung cấp cho bạn bất kỳ loại kẹo nào cho tâm trí của bạn là bạn đến từ một nền Java mà tất cả ý định và mục đích cung cấp bản dịch trực tiếp và đơn giản thành C++. Không phải là tốt nhất C + + để chắc chắn, nhưng có thể làm việc C + + thực hiện ...

... Lý do cho thành ngữ khác nhau trong ví dụ PS của bạn không có gì để làm với tài liệu tham khảo (Java không có: Java có trỏ tới các đối tượng nhưng không tham chiếu, nhưng C++ không có tham chiếu cũng như con trỏ) và mọi thứ cần làm với thực tế là trong phân bổ bộ nhớ Java tương đối rẻ trong khi trong C++ thì không (vì trong Java chi phí cấp phát bộ nhớ là được phân bổ trên tất cả mọi thứ mà VM cần phân bổ anyway - trong khi đó, trong C++ nó không phải như vậy trong Java VM đảm bảo rằng bộ nhớ chỉ được phân bổ khi cần). Vì vậy, trong C++ hiệu quả bạn thấy rằng mọi người tránh rất nhiều cuộc gọi mới dự phòng trong một vòng lặp chặt chẽ trong khi ở Java mọi người có thể thoải mái tạo ra các đối tượng tạm thời tất cả những gì họ muốn.

+0

Bạn có thể xây dựng thêm hoặc đưa ra một số gợi ý về lý do tại sao phân bổ bộ nhớ Java là rẻ trong khi nó dựa trên đống? Câu hỏi của tôi là tại sao C++ không thể thực hiện phân bổ bộ nhớ dựa trên heap hiệu quả như Java. Cảm ơn! –

+0

Bởi vì trong C/C++ một cuộc gọi mới hoặc malloc là tốn kém, trong khi ở Java, số lượng cuộc gọi mới ít hơn "đặt trước" một chút bộ nhớ được phân bổ trước bởi JVM. Tương tự như vậy, giải phóng bộ nhớ không cần phải đi qua các cuộc gọi hệ điều hành đắt tiền. Hay nói cách khác chi phí của một cuộc gọi malloc/new trong JVM cơ bản được phân bổ trên * tất cả * cuộc gọi mới trong mã Java, vì vậy chi phí trung bình của một cuộc gọi mới trong mã Java là khá nhỏ so với tương đương C++ . – user268396

+0

@ hungh3, trong C++ bạn cũng có thể phân bổ trước các nhóm đối tượng như Java, và bỏ chúng ra và đưa chúng trở lại vào hồ bơi (trong suốt, quá - C++ là tốt) và do đó tránh đi hệ điều hành mỗi lần. - Đối với giá của một mã nhỏ. – JDonner

2

Sự thật đơn giản là phải mất một chút thời gian để học cách suy nghĩ bằng một ngôn ngữ, ví dụ: thực hành tốt nhất.Đó là một quá trình lâu dài, nơi bạn bắt đầu với việc học cú pháp và có lẽ lúc đầu áp dụng các mô hình ngôn ngữ khác lúc đầu để tìm đường đi của bạn. Đúng là nếu bạn đã chọn một ngôn ngữ rất khác với Java-cú pháp-khôn ngoan cũng như mô hình-wuse bạn có thể nhận thấy những khác biệt này sớm hơn nhưng đừng đánh giá thấp C++ như một mô hình khác.

C++ là ngôn ngữ rất phức tạp để học, tuy nhiên đó là ngôn ngữ có thể tạo ấn tượng rằng dễ học đặc biệt vì cú pháp tương tự như một số ngôn ngữ khác. Một chủ đề lớn là lập trình mẫu mẫu, sử dụng một khuôn mẫu khá đơn giản, tuy nhiên nếu bạn xem thư viện mẫu boost bạn sẽ có thể khá phức tạp và xây dựng một thư viện như vậy không dành cho những người yếu tim.

Học một ngôn ngữ không chỉ là về việc học một cú pháp, mà là học cách suy nghĩ bằng ngôn ngữ đó.

Điều đó nói rằng, C++ là một trong những ngôn ngữ cho phép bạn tự do và kiểm soát nhiều như bạn muốn, đôi khi quá nhiều tự do.

+0

+1 Tôi thích của bạn, có thể là cos của * Học một ngôn ngữ không chỉ là về học một cú pháp, về việc học cách suy nghĩ bằng ngôn ngữ đó * .. :) – liaK

+1

+1 cho "đôi khi quá nhiều tự do". Tôi nghĩ cũng giống như trong cuộc sống, (nhiều hơn) tự do thường đi kèm với một mức giá (cao hơn), chẳng hạn như an ninh ít hơn. Và các chương trình mã hóa "bình thường" có thể không * thực sự * cần nhiều tự do ... nhưng các công cụ và chương trình tuyệt vời do các tin tặc thực sự tạo ra. –

2

Chắc chắn có một cái nhìn tại www.boost.org, đó sẽ là một trải nghiệm thay đổi tư duy.

Đối với câu hỏi trong Post Scriptum: nếu biểu mẫu đầu tiên sẽ liên quan đến bản sao hay không: tùy thuộc và phụ thuộc vào nhiều yếu tố.

Trong C++ hiện tại:

Đầu tiên là nếu trình biên dịch hỗ trợ RVO và đặc biệt là khi nó cũng hỗ trợ NRVO, rất có thể là bản sao cao sẽ không diễn ra. Sau đó, nó phụ thuộc vào cách các chức năng được viết:

A computeAndReturnA() 
{ 
    return A(x, y); // no copy almost for sure 
} 

A computeAndReturnA() 
{ 
    A a; 
    a.f(); 
    a.g(); 
    return a; // no copy if compiler implements NRVO 
} 

A computeAndReturnA() 
{ 
    A a; 
    while (condition1) { 
     a.f(); 
     if (condition2) 
     return A(); // copy will take place 
    } 
    a.g(); 
    return a; // copy will take place 
} 

Sau đó, nó phụ thuộc vào cách bạn gọi hàm:

A a1 = computeAndReturnA(); // no copy if function body written appropriately, 
           // return value will be constructed directly in a1 
A a2; 
a2.foo(); 
a2 = computeAndReturnA();  // copy regardless of function body, 
           // return value can't directly be constructed in a2 
           // as a2 is already constructed 

Trong C sắp tới ++ (tháng 3 năm 2011?):

Lý do tương tự như đối với C++ hiện tại. Tuy nhiên, nếu lý do đó cho thấy rằng bản sao sẽ được thực hiện, và nếu lớp (A ở đây) đã di chuyển hàm tạo và di chuyển toán tử gán, thì 'di chuyển' và không 'sao chép' sẽ diễn ra. Trong trường hợp lý tưởng, việc di chuyển sẽ được ưu tiên cũng như bạn được xây dựng trực tiếp, nhưng nếu không bạn sẽ di chuyển trong trường hợp xấu nhất, tất nhiên miễn là lớp học được trả lại là di chuyển.

Tôi nghĩ rằng bạn sẽ tìm thấy bài viết này thú vị và nhiều thông tin: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

+0

Cảm ơn bạn đã giải thích. Tôi thực sự học được rất nhiều từ bạn và liên kết. Btw, bạn có biết làm thế nào tôi có thể kiểm tra xem một trình biên dịch thực hiện RVO hoặc NRVO hay không? –

+1

Hầu hết các trình biên dịch * hiện đại đều làm cả hai, nếu không phải tất cả chúng. GCC bắt đầu từ 3.1 (khoảng năm 2002). Nhưng để chắc chắn tôi nghĩ cách duy nhất để kiểm tra là xem xét việc tháo gỡ mã được tạo ra và xem liệu hàm có được gọi là một con trỏ ẩn (địa chỉ) để xây dựng giá trị trả về hay không. Hoặc trình biên dịch có thể chỉ ra nếu nó hỗ trợ RVO trong tài liệu của nó. Ví dụ: http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx – usta

+0

Usta, cảm ơn lời khuyên của bạn. –

2

C++ là nhiều tổng quát hơn Java, theo nghĩa là nó là, như chỉ trong câu trả lời khác, một ngôn ngữ mô hình đa, nơi như Java chỉ nhấn mạnh lập trình hướng đối tượng (và một cách duy nhất để làm OOP, tại đó).

Bạn chắc chắn có thể làm nhiều việc trong C++ mà bạn không thể mơ ước trong Java. Tuy nhiên, đối với một người có nền Java, tôi cho rằng C++ là một phương tiện học tập rất tệ, vì nó quá dễ dàng để chỉ đơn giản là viết mã bằng Java với một vài câu lệnh "xóa" ở đây và ở đó.

Nếu bạn muốn có một số kinh nghiệm thay đổi ý định, bạn nên học một ngôn ngữ chủ động nhấn mạnh một mô hình khác, thay vì ngôn ngữ cho phép bạn chọn bất kỳ mô hình nào bạn muốn.

Tôi sẽ đề xuất một trong Haskell (lập trình hàm), Erlang (một cách tiếp cận không phổ biến để đồng thời), Factor (lập trình dựa trên stack), Prolog (lập trình logic), Common Lisp (CLOS & macro), Javascript (prototype- dựa trên OOP, tức là không có các lớp).

Những ý kiến ​​này, theo ý kiến ​​của tôi, là những trải nghiệm học tập thay đổi tâm trí. Tôi cho rằng, mặc dù họ hỗ trợ nhiều thứ mà Java không, Python và Ruby vẫn còn khá gần với mô hình Java; thực sự, với một nền Java, nó sẽ khá dễ dàng để xem chúng như là một skin khác trên cùng một mô hình, với một cú pháp hơi khác và không có khai báo kiểu nào.

Quan điểm của tôi là, nếu bạn muốn thổi hồn, bạn phải học một mô hình mới. Và trong khi chắc chắn có thể học các mô hình mới về một ngôn ngữ đầy đủ mạnh mẽ như C++, nó sẽ dễ dàng hơn nhiều để tìm hiểu mô hình mới thông qua việc học một ngôn ngữ buộc bạn sử dụng mô hình đó.

Để biết tổng quan ngắn gọn về một số ý tưởng thay đổi ý định, bạn có thể xem these video lectures.

+0

Cảm ơn câu trả lời của bạn. Câu trả lời của bạn có ý nghĩa rất nhiều. Và cảm ơn cho các liên kết, cũng có. Btw, Dường như với tôi giống như tất cả những tài nguyên quý giá này nằm rải rác khắp Web, tôi không biết liệu bạn có biết ai đã cố gắng tập hợp và phân loại các tài nguyên này (như Google Directory) không? –

Các vấn đề liên quan