C++與Java文法上的不同

來源:互聯網
上載者:User

標籤:其它   pointer   指標   #define   機制   童鞋   int   change   value   

最近學習演算法和刷題基本都是用C++寫的程式,在這個過程中,發現C++和Java在文法上有很多相同點,但也有很多不同點,而這些不同點對於已經掌握Java的程式員來說,理解C++代碼可能會有些吃力甚至困難,在踩過了一個又一個坑後,我決定把這些不同記錄下來,可能涵蓋的不是很全,所以本文會持續更新。

零、目錄1. new關鍵字2. C++執行個體化對象的幾種方式3. C++初始設定式4. C++建構函式後的冒號5. C++中難以省略的分號;6. C++中的::7. C++中的*、&、->8. C++函數前或者函數後的const一、new關鍵字
// C++中:MyClass* a = new MyClass();delete a;// Java中:MyClass a = new MyClass();
  1. C++中new關鍵字執行個體化對象之後返回的是一個對象的指標,所以需要定義指標;而Java中定義對象時返回的其實也是一個指標(引用),但是在Java中不需要顯示的定義指標。
    不同點
  2. C++中通過new關鍵字執行個體化的對象在使用完畢後需要使用delete關鍵字手動釋放記憶體;而Java中由於記憶體回收機制的存在,我們無需手動釋放記憶體。
二、C++執行個體化對象的兩種方式
// 方式一MyClass* a = new MyClass();delete a;// 方式二MyClass b();
  1. 方式一中new關鍵字做了三件事:首先在堆記憶體上獲得記憶體空間(類似malloc函數),然後調用類的建構函式,最後返回該記憶體空間的指標;因為是在堆記憶體的動態分配的記憶體空間,所以最後需要調用delete函數釋放這一部分記憶體空間。
  2. 方式二中直接在棧記憶體上分配了儲存空間,類似於基本類型的定義,所以無需手動釋放記憶體空間;但是當對象資訊量較大時,這種做法會佔用很多記憶體,影響程式效率。
三、C++初始設定式
int a(10); // 等效於 int a = 10;

與java不同,C++除了使用指派陳述式初始設定變數之外,還可以使用上述初始設定式對變數進行初始化,其效果相同。

四、C++建構函式後的冒號
// 初始設定式class MyClass {  public:    const int a;    int b;    MyClass(int aVal, int bVal):a(aVal), b(bVal) {}};// 非初始設定式,無法通過編譯,編譯時間會報以下錯誤:// ‘const int MyClass::a‘ should be initializedclass MyClass {  public:    const int a;    int b;    MyClass(int aVal, int bVal) {       a = aVal;       b = bVal;    }};

這個文法其實就是上述第四點中的初始設定式,但這裡我們看到下面這種賦值方式在建構函式裡面會報錯,這又是為什麼呢?因為這裡我們的冒號初始化和指派陳述式乾的事情不太一樣:在冒號初始化時,只有冒號後面有相應變數的初始設定式,就會在為成員變數分配記憶體時進行初始化,所以常量a在分配記憶體時做了初始化操作,之後也沒有被改變值,所以不會報錯;而在使用指派陳述式時,建構函式在執行到函數體時已經為a分配了記憶體但卻沒有對其進行初始化,因此就會報should be initialized編譯錯誤了。

這種神奇的寫法我第一次見的時候也是驚訝了一波。

五、C++中難以省略的分號;

在上面例子中我們看到了C++類的定義後面也要加分號;我們知道在Java中類定義的大括弧後面都無需加分號。
之後查資料發現:
在C++中,除函數,及先行編譯指令外,其它的語句或程式碼片段結尾都必須要加分號。其中先行編譯指令是指,以#開頭的語句。常見的有,#include ,#define, #ifdef, #if, #elif, #else,#endif等。

六、C++中的::(範圍符)

C++的範圍符::用法有三,一一介紹如下

  1. 全域範圍符

    int a = 3;void test() {  int a = ::a;  cout << a << endl;}
    這裡就是將全域變數a的值通過全域範圍符的方式訪問到,然後將其值賦給test函數中的局部變數a。
  2. 類範圍符

    class MyClass {  public:void sayHello();};void MyClass::sayHello() {  cout << "hello world!" << endl;}
    這裡有點類似Java中定義介面和對介面進行實現;首先在類的定義中定義了一個函數sayHello,但是沒有具體函數體,然後在類的定義外,通過範圍符,在函數sayHello前加了一個MyClass::,相當於告訴編譯器,這個函數就是MyClass類的sayHello方法的具體實現。
  3. 命名空間範圍符

    std::cout << "hello world!" << endl;

    這裡std就是命名空間,這樣的用法相當於using namespace std;

七、C++中的*、&、->
class MyClass {  public:    int a;    MyClass(int aVal):a(aVal){}};int main () {  MyClass obj(5);  MyClass* objPointer = new MyClass(3);  // 常規操作  cout << obj.a << endl;  // 取指標操作  cout << (*objPointer).a << endl;  // ->操作  cout << objPointer->a << endl;  // 取地址操作  cout << (&obj)->a << endl;  // new出來的對象別忘了釋放記憶體哦  delete objPointer;  return 0;}

在C++中:

  1. *表示訪問指標a指向的變數;
  2. &表示取得變數的地址;
  3. .表示訪問對象的的成員變數或者函數;(與Java相同)
  4. ->表示訪問指標指向的對象的成員變數或者函數;

    指標內容實在太多,這裡就不贅述了,有興趣的童鞋可以參考菜鳥教程

八、C++函數名前或者函數名後的const
  1. 函數名前的const

    const int getVal() {  const int a = 3;  return a;}int main() {  cout << getVal() << endl;}
    就是定義函數的傳回型別,規定返回變數類型必須為const。
  2. 函數名後的const(用於類的成員函數中)

    class MyClass {  public:int a;MyClass(int aVal):a(aVal){}void sayHello() const {  cout << "a value is: " << a << endl;}// 編譯報錯:assignment of member ‘MyClass::a‘ in read-only objectvoid changeA() const {  a = 5;}};

    函數名後面的const表示是該函數為常成員函數,該函數不能修改對象內的任何成員變數,只能發生讀操作,不能發生寫操作。這樣可以對成員變數起到保護作用。

C++與Java文法上的不同

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.