接續[【C語言基礎系列】](http://www.jianshu.com/p/4701cd1e1914)
### 前言
在進行NDK開發的時候 , 我們使用的很多第三方庫 , 大多數都是使用的C/C++編寫的 , 有些可能是C和C++混編的 。如,我在NDK系列中提到的[增量更新](http://www.jianshu.com/p/47d6c115f7ca)使用的兩個庫 `bsdiff`和`bzip2` 。那么 , 我們在學完C語言之后 , 有必要研究一下C++,因為C++是C的拓展 , 加入了面向對象和模板技術 ,那么基本語法就不用介紹了。本系列假定你具有一定的編程經驗,對面向對象有一定的了解 。
### 命名空間
在Java中 , 我們使用包來區分文件的所在路徑和類來自哪個包 ,使用`package`來聲明文件在哪個文件目錄下 , 進而在使用的時候可以區分 , 來自不同的包的相同類名 。在C++里面沒有`package`關鍵字 , 而是使用`namespace`來作為區分 , 在PHP中也是如此 , 在PHP5.0的時候引入的了`namespace`來做為區分不同路徑下的同名函數和類 。
> 定義namespace
```c++
/*
cpp namespace demo
*/
#include <iostream>
/*
自定義命名空間 , 相當于Java中的包 。
命名空間可以嵌套
*/
namespace NSP_A
{
class A {
public:
void sayHello() {
std::cout << "say Hello " << std::endl;
}
};
// 嵌套namespace
namespace NSP_A_1
{
class A {
public:
void sayHello() {
std::cout << "Say Hello 1" << std::endl;
}
};
}
}
```
> 使用namespace
```c++
// 標準命名空間 (包含很多標準的定義)
using namespace std;
// use namespace
using namespace NSP_A;
/*
使用自定義命名空間
*/
void useNameSpace() {
A a;
a.sayHello();
// 嵌套命名空間使用
NSP_A_1::A a2;
a2.sayHello();
}
```
在C++中也定義了一些標準命名空間 , 如`std` ,C++中也兼容C語言語法 , 可以引入C語言頭文件,使用C標準函數 。
### C++ 類 與 結構體
C++是面向對象語言 , 面向對象語言的一大特征就是可以將類型整合起來 , 可以創建類型實例 。
> 創建C++類
```c++
/*
cpp class type
*/
#include <iostream>
using namespace std;
namespace CPP_CLASS
{
class Animal {
// C++ 共用權限訪問修飾符
private:
char* name;
int age;
public:
void setName(char* name) {
this->name = name;
}
void setAge(int age) {
this->age = age;
}
void showInfo() {
cout << "名稱:" << this->name << " 年歲:" << this->age << endl;
}
};
}
```
寫法都是類似的 , C++字段和函數都是采用的共享權限修飾符 , 值得注意的是 , 在C++中 , 結構體里面的屬性和函數也具有權限訪問修飾符 。
```c++
/*
CPP Struct
*/
namespace CPP_STRUCT
{
// C++結構體與C結構不同之處在于 , 在C++中結構體內字段函數可以有權限修飾符,用法和類用法一致
// 和類不同的是 , struct 不能繼承
struct Person
{
private:
char* name;
int age;
public:
void setName(char* name) {
this->name = name;
}
void setAge(int age) {
this->age = age;
}
void showPersonInfo() {
cout << "姓名: " << this->name << " 年齡: " << this->age << endl;
}
};
}
```
結構體和類最大的不同是 , 結構體不能繼承 , 不能進行抽象化。
> 使用C++類 與 結構體
```c++
/* CPP Class */
using namespace CPP_CLASS;
/* CPP Struct */
using namespace CPP_STRUCT;
/*
Simple CPP Class
*/
void useCppClass() {
Animal animal;
animal.setName("dog");
animal.setAge(2);
animal.showInfo();
}
/*
C and C++ 結構體的區別
*/
void useCppStruct() {
Person p;
p.setName("zeno");
p.setAge(20);
p.showPersonInfo();
}
```
在C++中 , 使用類與使用結構體 , 用法并無二致 , 只是結構不能使用`new`而類可以使用 , `new`出來的是一個對象指針 。
### 引用
相信大家對引用并不陌生 , 在Java中 , 我們常常將對象變量叫做對象引用 , 在C++中也不例外 , C++中的引用也可以作為對象變量 , 但C++中的引用不會開辟新的空間 , 去存儲指向對象內存空間的地址值 , 而是作為對象引用的一個別名 。
> 簡單示意圖

> 引用示例
```c++
/*
CPP 引用
*/
#include <iostream>
namespace CPP_QUOTE {
class Quote {
public:
int x = 10;
// 引用 ,就是傳入變量的別名,引用不會開辟新的內存空間,如同指針一樣,指向的是傳入變量的內存空間
// 一般作為函數參數或返回值
// 引用使用方便
void swip(int &a, int &b) {
int c = 0;
c = a;
a = b;
b = c;
}
// 指針交換
void swip_p(int* a , int* b) {
int c = 0;
c = *a;
*a = *b;
*b = c;
}
};
}
```
引用在函數傳值的時候, 可以當指針來使用 , 引用最廣泛的用途就在于 , 在函數參數中 , 充當指針用 。
> 引用使用
```c++
/* C++ 引用的使用 */
/* CPP Quote */
using namespace CPP_QUOTE;
void useCppQuote() {
Quote q;
// Quote q 的別名
Quote &q1 = q;
q1.x = 100;
printf("q的內存地址 : %#x , q1的內存地址:%#x\n", &q, &q1);
cout << " q == " << q.x << endl;
int x = 20, y = 40;
q1.swip(x, y);
cout << " q swipe x = " << x << " y = " << y << endl;
// 指針值交換
q1.swip_p(&x, &y);
cout << " 指針值交換 : x = " << x << " y = " << y << endl;
}
```
打印對象的地址與引用變量的地址 , 我們會發現內存地址是一致 , 因為引用是變量的別名 , 不會創建新的內存空間。
### 結語
有了C語言基礎 , 學C++ , 只要掌握語法的差異性和一些C++的特性 , C++還是很容易上手的 , 基礎語法 , 需要動手練 , 多做實驗 , 慢慢就會熟能生巧 。
- 簡介
- C語言基礎及指針①語法基礎
- C語言基礎及指針②之指針內存分析
- C語言基礎及指針③函數與二級指針
- C語言基礎及指針④函數指針
- C語言基礎及指針⑤動態內存分配
- C語言基礎及指針⑥字符操作
- C語言基礎及指針⑦結構體與指針
- C語言基礎及指針⑧文件IO
- C語言基礎及指針⑨聯合體與枚舉
- C語言基礎及指針⑩預編譯及jni.h分析
- JNI開發系列①JNI概念及開發流程
- JNI開發系列②.h頭文件分析
- JNI開發系列③C語言調用Java字段與方法
- JNI開發系列④C語言調用構造方法
- JNI開發系列⑤對象引用的處理
- NDK開發基礎①使用Android Studio編寫NDK
- NDK開發基礎②文件加密解密與分割合并
- NDK開發基礎③增量更新之服務器端生成差分包
- C++基礎①命名空間結構體和引用