最近學習算法和刷題基本都是用C++寫的程序,在這個過程當中,發現C++和Java在語法上有不少相同點,但也有不少不一樣點,而這些不一樣點對於已經掌握Java的程序員來講,理解C++代碼可能會有些吃力甚至困難,在踩過了一個又一個坑後,我決定把這些不一樣記錄下來,可能涵蓋的不是很全,因此本文會持續更新。html
// C++中: MyClass* a = new MyClass(); delete a; // Java中: MyClass a = new MyClass();
// 方式一 MyClass* a = new MyClass(); delete a; // 方式二 MyClass b(params...); // 該方式將會調用有參數的構造函數 MyClass c; //該方式將會調用無參數的構造函數
int a(10); // 等效於 int a = 10;
與java不一樣,C++除了使用賦值語句初始化變量以外,還可使用上述初始化表達式對變量進行初始化,其效果相同。java
// 初始化表達式 class MyClass { public: const int a; int b; MyClass(int aVal, int bVal):a(aVal), b(bVal) {} }; // 非初始化表達式,沒法經過編譯,編譯時會報如下錯誤: // 'const int MyClass::a' should be initialized class MyClass { public: const int a; int b; MyClass(int aVal, int bVal) { a = aVal; b = bVal; } };
這個語法其實就是上述第四點中的初始化表達式,但這裏咱們看到下面這種賦值方式在構造函數裏面會報錯,這又是爲何呢?由於這裏咱們的冒號初始化和賦值語句乾的事情不太同樣:在冒號初始化時,只有冒號後面有相應變量的初始化表達式,就會在爲成員變量分配內存時進行初始化,因此常量a在分配內存時作了初始化操做,以後也沒有被改變值,因此不會報錯;而在使用賦值語句時,構造函數在執行到函數體時已經爲a分配了內存但卻沒有對其進行初始化,所以就會報should be initialized編譯錯誤了。程序員
這種神奇的寫法我第一次見的時候也是驚訝了一波。算法
在上面例子中咱們看到了C++類的定義後面也要加分號;咱們知道在Java中類定義的大括號後面都無需加分號。
以後查資料發現:
在C++中,除函數,及預編譯指令外,其它的語句或代碼段結尾都必需要加分號。其中預編譯指令是指,以#開頭的語句。常見的有,#include ,#define, #ifdef, #if, #elif, #else,#endif等。函數
C++的做用域符::用法有三,一一介紹以下學習
int a = 3; void test() { int a = ::a; cout << a << endl; }
這裏就是將全局變量a的值經過全局做用域符的方式訪問到,而後將其值賦給test函數中的局部變量a。spa
class MyClass { public: void sayHello(); }; void MyClass::sayHello() { cout << "hello world!" << endl; }
這裏有點相似Java中定義接口和對接口進行實現;首先在類的定義中定義了一個函數sayHello,可是沒有具體函數體,而後在類的定義外,經過做用域符,在函數sayHello前加了一個MyClass::,至關於告訴編譯器,這個函數就是MyClass類的sayHello方法的具體實現。指針
std::cout << "hello world!" << endl;
這裏std就是命名空間,這樣的用法至關於using namespace std;code
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++中:htm
->表示訪問指針指向的對象的成員變量或者函數;
指針內容實在太多,這裏就不贅述了,有興趣的童鞋能夠參考菜鳥教程
const int getVal() { const int a = 3; return a; } int main() { cout << getVal() << endl; }
就是定義函數的返回類型,規定返回變量類型必須爲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 object void changeA() const { a = 5; } };
函數名後面的const表示是該函數爲常成員函數,該函數不能修改對象內的任何成員變量,只能發生讀操做,不能發生寫操做。這樣能夠對成員變量起到保護做用。
MyClass* a = new MyClass(); delete a; // 省略下面這句運行時會出現如下錯誤: // pointer being freed was not allocated a = NULL; delete a;
對一個非空指針delete後,若沒有置爲NULL,若再次delete的話,有可能出現問題。而C++標準規定:delete空指針是合法的,沒有反作用。因此每次delete以後要將指針的值置爲NULL。這是一個不得不養成的好習慣,hah...