NDK開發(fā)(三) - C++基礎(chǔ)

C是面向過程的語言甘耿,而C++是面向?qū)ο蟮拇瓴纭H绻荍ava開發(fā)者會(huì)更習(xí)慣與使用C++芽突,從Android系統(tǒng)源碼能看出试浙,Native層開發(fā)主要采用的也是C++,C語言更多的還是作為Kernel層的開發(fā)語言寞蚌。因此也有必要針對(duì)C++來做一個(gè)梳理田巴,從語言上,C++完全兼容C睬澡,很多東西都是相通的固额,因此與C相同的內(nèi)容就不再贅述。

一煞聪、命名空間

C++引入命名空間(namespace)斗躏,主要是避免命名沖突的問題。
namespace有系統(tǒng)定義的昔脯,也可以自定義啄糙。
舉例:
C++標(biāo)準(zhǔn)程序庫中的所有標(biāo)識(shí)符都被定義于一個(gè)名為std的namespace中。
使用C++打釉浦伞:
1)使用命名空間去點(diǎn)對(duì)應(yīng)標(biāo)識(shí)符:

std::cout << "Hello, World!" << std::endl;

2)使用命名空間對(duì)應(yīng)標(biāo)識(shí)符:

using std::cout;
using std::endl;
cout << "Hello, World!" << endl;

3)直接使用命名空間:

using namespace std;
cout << "Hello, World!" << endl;

二隧饼、引用與指針

C++在C指針的基礎(chǔ)上,增加引用的支持静陈。
引用是別名燕雁,指針是地址。二者區(qū)別:

  • 指針可以被重新賦值以指向另一個(gè)不同的對(duì)象鲸拥。而引用則總是指向在初始化時(shí)被指定的對(duì)象拐格,以后不能改變,但是指定的對(duì)象其內(nèi)存可以改變刑赶。
  • 程序?yàn)橹羔樧兞糠峙鋬?nèi)存區(qū)域捏浊,可以指向空值。而不為引用分配內(nèi)存區(qū)域撞叨,不可指向空值金踪。

舉例:

//指針傳遞
void swap(int *a, int *b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

//引用傳遞
void swap1(int &a, int &b) {
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

int main() {
   int a = 1;
    int b = 2;
    swap(&a, &b);
    swap1(a, b);
    return 0;
}

二、字符串

C++引入string

#include <string>
int main() {
    string str = "hello";
    cout << str << endl;
    return 0;
}

三牵敷、面向?qū)ο?/h4>

這部分是C++區(qū)別于C的核心內(nèi)容胡岔。

3.1 類與對(duì)象
class Shape {
/**
 * 訪問修飾符
 * public
 * private 只有類和友元函數(shù)可以訪問私有成員
 * protect 類、友元函數(shù)枷餐、子類可以訪問受保護(hù)成員
 */
public:
    //無參構(gòu)造方法(直接實(shí)現(xiàn))
    Shape() {
   
    };

    //帶參構(gòu)造方法聲明(外部實(shí)現(xiàn))
    Shape(double len);

    //析構(gòu)函數(shù)
    ~Shape() {
     //在每次刪除所創(chuàng)建的對(duì)象時(shí)執(zhí)行, 主要做些釋放資源的事
    }

    //靜態(tài)成員
    static int objectCount;

    //成員變量
    int width;
    int height;

    //成員函數(shù)聲明(外部實(shí)現(xiàn))
    int getArea1();

    //成員函數(shù)直接實(shí)現(xiàn)
    int getArea2() {
        return 0;
    }

    /**
     * 友元函數(shù):類的友元函數(shù)是實(shí)現(xiàn)在類外部的姐军,但具有訪問類private和protected的成員變量與函數(shù)
     * 注意:
     *    友元函數(shù)不能使用this
     *    友元函數(shù)不能被子類繼承
     * @param shape
     */
    friend void printLength(Shape shape);

protected:
    int length;
private:
    void show() {
        cout << "show" << endl;
    }
};

//成員函數(shù)定義
int Shape::getArea1() {
    return 0;
}

//帶參構(gòu)造方法
Shape::Shape(double width) {
    this->width = width;
    cout << "constructor create:length " << width << endl;
}

//友元函數(shù)實(shí)現(xiàn)
void printLength(Shape shape) {
    cout << "length:" << shape.length << endl;
    shape.show();
}

//初始化靜態(tài)變量
int Shape::objectCount = 1;

int main() {
    //無參構(gòu)造函數(shù)
    Shape shape;
    //有參構(gòu)造函數(shù)三種調(diào)用方法:
    Shape shape1(1.23);
    Shape shape2 = (1.23);
    Shape shape3 = Shape(1.23);
    cout << "objectCount:" << Shape::objectCount << endl;

    printLength(shape);
    return 0;
}
淺拷貝:拷貝指針變量的值。
深拷貝:拷貝指針?biāo)赶虻膬?nèi)存空間尖淘。

3.2 抽象類與繼承
class Shape {
public:
   //純虛函數(shù), =0 告訴編譯器奕锌,函數(shù)沒有主體
    virtual int getArea() = 0;

protected:
    int width = 1;
    int height = 2;
};

//派生子類
//多繼承:class <派生類名>:<訪問控制1><基類名1>,<訪問控制2><基類名2>,…
class Rectangle : public Shape {
public:
    int getArea() {
        return width * height;
    }
};

int main() {
    Rectangle rect;
    cout << rect.getArea() << endl;
}

類中至少有一個(gè)函數(shù)被聲明為純虛函數(shù),則這個(gè)類就是抽象類村生。
抽象類不能被用于實(shí)例化對(duì)象惊暴,它只能作為接口使用。

3.3 重載

函數(shù)重載

class printData
{
   public:
     //print重載
      void print(int i) {
        cout << "整數(shù)為: " << i << endl;
      }
 
      void print(double  f) {
        cout << "浮點(diǎn)數(shù)為: " << f << endl;
      }
 
};

運(yùn)算符重載

class Shape {

public:
    int width = 1;

    Shape() {}

    Shape(int w) {
        width = w;
    }
    
    //重載 + 運(yùn)算符趁桃,用于把兩個(gè)Shape對(duì)象相加
    Shape operator+(const Shape &shape) {
        Shape s;
        s.width = width + shape.width;
        return s;
    }
};

int main() {
    Shape shape;
    Shape shape1 = Shape(2);
    const Shape &s = shape.operator+(shape1);
    cout << s.width << endl;
}

支持重載的運(yùn)算符:

雙目算術(shù)運(yùn)算符: + 辽话,-,卫病,/油啤,%
關(guān)系運(yùn)算符: ==,!=蟀苛, < 益咬,> ,<=帜平,>=
邏輯運(yùn)算符: ||幽告,&&,!
單目運(yùn)算符: + 裆甩,-冗锁,
,&
自增自減運(yùn)算符: ++嗤栓,--
位運(yùn)算符: | 冻河,& ,~茉帅,^叨叙,<< ,>>
賦值運(yùn)算符: =, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=
空間申請(qǐng)與釋放: new, delete, new[ ] , delete[]
其他運(yùn)算符: ()(函數(shù)調(diào)用)担敌,->(成員訪問)摔敛,,(逗號(hào)),

3.4 多態(tài)

配合虛函數(shù)實(shí)現(xiàn)多態(tài)

class Shape {
public:
    //虛函數(shù)
    virtual int area() {
        cout << "Parent class area :" << endl;
        return 0;
    }
};

class Rectangle : public Shape {
public:
    int area() {
        cout << "Rectangle class area" << endl;
    }
};

class Triangle : public Shape {
public:

    int area() {
        cout << "Triangle class area" << endl;
    }
};

int main() {
    //父類指針指向不同子類對(duì)象地址全封,這是C++多態(tài)一般使用方式
    Shape *shape;
    Rectangle rectangle;
    Triangle triangle;

    shape = &rectangle;
    shape->area();

    shape = &triangle;
    shape->area();
}

四马昙、動(dòng)態(tài)內(nèi)存分配

C++中使用new和delete來動(dòng)態(tài)分配和釋放內(nèi)存。malloc() 函數(shù)在 C 語言中就出現(xiàn)了刹悴,在 C++ 中仍然存在行楞,new 與 malloc() 函數(shù)相比,其主要的優(yōu)點(diǎn)是:new 不僅分配了內(nèi)存土匀,它還創(chuàng)建了對(duì)象子房。
//為對(duì)象動(dòng)態(tài)分配內(nèi)存

Shape *pShape = new Shape();

//為對(duì)象釋放內(nèi)存
delete pShape;

五、信號(hào)處理

#include <signal.h>

static void signalHandler(int signum) {
    cout << "abort signal (" << signum << ") received.\n";
    exit(signum);
}

int main() {
    // 注冊(cè)信號(hào) SIGINT 和信號(hào)處理程序,因?yàn)樗⒉粚儆赑OSIX(Portable Operating System Interface)標(biāo)準(zhǔn),即:可移植操作系統(tǒng)接口
    // 在各類 UNIX 平臺(tái)上的實(shí)現(xiàn)不盡相同,因此其用途受到了一定的限制证杭。
    signal(SIGABRT, signalHandler);
    /**
     * sigaction 結(jié)構(gòu)體
     *
     * sa_handler: 設(shè)置處理函數(shù)handler
     * sig.sa_sigaction: 也是設(shè)置處理函數(shù)handler田度,但是與sa_handler對(duì)應(yīng)的handler傳參不一樣
     * sa_mask: 用來設(shè)置在處理該信號(hào)時(shí)暫時(shí)將sa_mask指定的信號(hào)集擱置
     * sa_flags:
     *   SA_ONSTACK      0x0001  take signal on signal stack
     *   SA_RESTART      0x0002  restart system on signal return
     *   SA_RESETHAND    0x0004   reset to SIG_DFL when taking signal
     *   SA_NOCLDSTOP    0x0008  do not generate SIGCHLD on child stop
     *   SA_NODEFER      0x0010  don't mask the signal we're delivering
     *   SA_NOCLDWAIT    0x0020  don't keep zombies around
     *   SA_SIGINFO      0x0040  signal handler with SA_SIGINFO args
     */
    struct sigaction sig;
    sig.sa_flags = SA_RESETHAND;
    sig.sa_handler = signalHandler;
    /**
     *  int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
     *
     *  signum: 要操作的信號(hào)
     *  act: 新的對(duì)信號(hào)的處理方式
     *  oldact: 原來對(duì)信號(hào)的處理方式
     *  return: 0表示成功,-1表示有錯(cuò)誤發(fā)生
     */
    sigaction(SIGABRT, &sig, NULL);
    abort();
}

六、模板

類似java泛型

6.1 函數(shù)模板
template<typename T>
void swap_(T &a, T &b){
    T temp = a;
    a = b;
    b = temp;
}
int main(){
    //交換 int 變量的值
    int n1 = 100, n2 = 200;
    swap_(n1, n2);
    cout<<n1<<", "<<n2<<endl;

    //交換 float 變量的值
    float f1 = 12.5, f2 = 56.93;
    swap_(f1, f2);
    cout<<f1<<", "<<f2<<endl;

    return 0;
}
6.2 類模板
template<typename T1, typename T2>  //這里不能有分號(hào)
class Point
{
public:
    Point(T1 x, T2 y): m_x(x), m_y(y){ }
public:
    T1 getX() const;  //獲取x坐標(biāo)
    void setX(T1 x);  //設(shè)置x坐標(biāo)
    T2 getY() const;  //獲取y坐標(biāo)
    void setY(T2 y);  //設(shè)置y坐標(biāo)
private:
    T1 m_x;  //x坐標(biāo)
    T2 m_y;  //y坐標(biāo)
};

typename也可以用class

七解愤、類型轉(zhuǎn)換

轉(zhuǎn)換類型操作符 作用
const_cast 去掉類型的const或volatile屬性镇饺。
static_cast 無條件轉(zhuǎn)換,靜態(tài)類型轉(zhuǎn)換送讲。
dynamic_cast 有條件轉(zhuǎn)換奸笤,動(dòng)態(tài)類型轉(zhuǎn)換,運(yùn)行時(shí)檢查類型安全(轉(zhuǎn)換失敗返回NULL)哼鬓。
reinterpret_cast 僅重新解釋類型监右,但沒有進(jìn)行二進(jìn)制的轉(zhuǎn)換。

使用舉例:

class Person {
public:
    Person() {}
    ~Person() {}

    int age;

    virtual void character() {};
};

class Student : public Person {
public:
    int classId;
};

void func() {}

typedef void(*FuncPtr)();//函數(shù)指針

int main() {
    //const_cast
    const Person p;
    //p.age = 10;//不能直接修改const類型
    Person per = const_cast<Person &>(p);
    per.age = 10;
    cout << "age:" << per.age << endl;

    //static_cast
    int n = 6;
    double d = static_cast<double>(n); //基本類型轉(zhuǎn)換

    //dynamic_cast
    Person *person = new Student();
    Student *stu = dynamic_cast<Student *>(person);//子類->父類异希,動(dòng)態(tài)類型轉(zhuǎn)換

    //reinterpret_cast
    FuncPtr funcPtr = reinterpret_cast<FuncPtr>(&func);//不同函數(shù)指針類型之間進(jìn)行轉(zhuǎn)換
}

總結(jié):

  • 去const屬性用const_cast
  • 基本類型轉(zhuǎn)換用static_cast
  • 多態(tài)類之間的類型轉(zhuǎn)換用dynamic_cast
  • 不同類型的指針類型轉(zhuǎn)換用reinterpret_cast

未完待續(xù)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載健盒,如需轉(zhuǎn)載請(qǐng)通過簡信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末宠互,一起剝皮案震驚了整個(gè)濱河市味榛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌予跌,老刑警劉巖搏色,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異券册,居然都是意外死亡频轿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門烁焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來航邢,“玉大人,你說我怎么就攤上這事骄蝇∩乓螅” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵九火,是天一觀的道長赚窃。 經(jīng)常有香客問我,道長岔激,這世上最難降的妖魔是什么勒极? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮虑鼎,結(jié)果婚禮上辱匿,老公的妹妹穿的比我還像新娘键痛。我一直安慰自己,他們只是感情好匾七,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布絮短。 她就那樣靜靜地躺著,像睡著了一般乐尊。 火紅的嫁衣襯著肌膚如雪戚丸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天扔嵌,我揣著相機(jī)與錄音,去河邊找鬼夺颤。 笑死痢缎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的世澜。 我是一名探鬼主播独旷,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼寥裂!你這毒婦竟也來了嵌洼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤封恰,失蹤者是張志新(化名)和其女友劉穎麻养,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诺舔,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鳖昌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了低飒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片许昨。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖褥赊,靈堂內(nèi)的尸體忽然破棺而出糕档,到底是詐尸還是另有隱情,我是刑警寧澤拌喉,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布速那,位于F島的核電站,受9級(jí)特大地震影響司光,放射性物質(zhì)發(fā)生泄漏琅坡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一残家、第九天 我趴在偏房一處隱蔽的房頂上張望榆俺。 院中可真熱鬧,春花似錦、人聲如沸茴晋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诺擅。三九已至市袖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烁涌,已是汗流浹背苍碟。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撮执,地道東北人微峰。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像抒钱,于是被迫代替她去往敵國和親蜓肆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一谋币、命名空間 standard:標(biāo)準(zhǔn)命名空間 命名空間類似于java中的包仗扬。 自定義命名空間 使用命名空間 ::為...
    小村醫(yī)閱讀 670評(píng)論 0 4
  • 前言 最近發(fā)現(xiàn)要學(xué)習(xí)C++來開發(fā)NDK,不得不把基礎(chǔ)的東西記錄下來蕾额,否則學(xué)的太多會(huì)混淆早芭,廢話不多說,開始記錄我的C...
    程序愛好者閱讀 389評(píng)論 0 1
  • 注:原文地址 前言:下文是很基礎(chǔ)的C++語法的 notes凡简,只是個(gè)人學(xué)習(xí) C++時(shí)逼友,針對(duì)自己不熟悉的知識(shí)點(diǎn)做的零散...
    cfanr閱讀 1,334評(píng)論 2 3
  • 最近看到自己之前剛開始學(xué)習(xí)的時(shí)候記的一些筆記就稍微整理了一下 c語言里的結(jié)構(gòu)體和c++里的結(jié)構(gòu)體有什么區(qū)別? 答:...
    你猜卟透_faa8閱讀 925評(píng)論 0 0
  • 夜鶯2517閱讀 127,718評(píng)論 1 9