1. 程式人生 > >C++學習筆記(一) 補充篇 基礎語法 — 參考慕課網 值得推薦!

C++學習筆記(一) 補充篇 基礎語法 — 參考慕課網 值得推薦!

C++與C的關係:所有C程式都可以在C++的編譯環境中執行。
c++比c語言之多添加了bool(布林型別)這裡寫圖片描述
新的初始初始化方法:
這裡寫圖片描述
隨用隨定:
這裡寫圖片描述
這裡寫圖片描述

#include <iostream>
#include <stdlib.h>
using namespace std;
int main(void)
{
cout<<"請輸入一個整數:"<<endl;
 int x=0;
 cin>>x;
cout<<oct<<x<<endl;//將該整數轉變成8進位制
cout<<dec<<x<<endl;//將該整數轉變成10進位制
cout<<hex<<x<<endl;//將該整數轉變成16進位制 cout<<"請輸入一個布林值(0/1):"<<endl; bool y=false; cin>>y; cout<<boolalpha<<y<<endl;//boolalpha表示的是布林值 system("pause"); return 0; }

這裡寫圖片描述
不由得嘚瑟一下,出結果了:這樣就可以再8進位制,10進位制,16進位制之間自由 轉換了。
C++的名稱空間:用名字劃取名字定義名稱空間namespace
這裡寫圖片描述
::表示的是,使用A名稱空間中的x。

2016年8月30日,我已經沒有那麼多時間了,我看了看那些課程,自己要加快速度了,目前自己打算光速掌握C++,我必須讓自己痛苦,然後掌握opencv至少在上研究生之前可以做吧人臉識別簡單的東西做出來吧。
引用:在計算機中,引用就是變數的別名。
這裡寫圖片描述
輸出的結果是10
結構體引用:
這裡寫圖片描述
這個結構體的名字叫做Coor。
然後在函式中使用這個結構體
這裡寫圖片描述
指標:
這裡寫圖片描述
說明:
這裡寫圖片描述

函式引數做引用時:
這裡寫圖片描述

c++的關鍵字const:是用來控制變數是否可以變化的。
const與變數之間的關係:也就是將一個變數變成一個常量。
const與指標型別的關係:const int*p=NULL;與 int const*P=NULL是完全等價的
函式引數預設值:
如果函式重要些預設值,預設值必須寫在最右邊。格式:
這裡寫圖片描述


紅字表示函式的宣告,黑字表示函式的定義。
函式過載:
這裡寫圖片描述
就是兩個函式的名字一樣,但是引數的個數不同,就是函式的過載。
行內函數:行內函數的關鍵字:inline。:
這裡寫圖片描述
就是將過程放到main函式裡面執行。
c++記憶體管理:申請和歸還記憶體資源。
申請記憶體,使用運算子:new;釋放記憶體,使用運算子:delete
申請記憶體 int*p=new int;釋放記憶體 delete*p.
申請一個塊記憶體:int *arr=new int[10];釋放塊記憶體: delete []arr;
判斷申請記憶體是否失敗:if(NULL==p)則說明記憶體分配失敗了,申請記憶體的時候需要判斷記憶體是否申請成功,釋放記憶體需要將其設為空指標
例子:

#include <stdlib.h>
#include <iostream>
using namespace std;

int main(void)
{
    int *p=new int;//申請記憶體
    //判斷申請記憶體是否成功
    if (NULL==p)
    {
        system ("pause");
        return 0;//如果申請失敗我們就退出‘如果申請成功了我們就將P賦值為20
    }
    *p=20;
    cout<<*p<<endl;
    delete p;//釋放記憶體
    p=NULL;//將指標設定為NULL
system ("pause");
return 0;
};

類(定義完類以後,一定要寫一個分號)
物件:
這裡寫圖片描述
資料成員+成員函式=完成的類
封裝:就是隻給使用者一些他們關心的資訊。
類的訪問限定符(作用:選擇暴露)1、public;2、protected;3、private
例項化,有兩種方式,一種是從堆中例項化,一種是從棧中例項化。
從棧中例項化:
這裡寫圖片描述
從堆中例項化:
這裡寫圖片描述
從堆中例項化需要釋放記憶體,而在棧中不用
。!
總結:先例項化,然後再訪問
物件成員的訪問方法
這裡寫圖片描述
舉例說明:

堆和棧之間的區別

記憶體的分配方式不同
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。

2、堆區(heap)— 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由OS回收 。注意它與資料結構中的堆是兩回事的方式例項化一個物件:

舉例說明

這是一個求三角形面積的程式

demo.cpp

#include <iostream>
#include "Triangle.h"
using namespace std;
int main()
{
    Src_Triangle *Src_dTriangle = new Src_Triangle();
    cout << "請輸入三角形的三條邊:" << "";
    cin >> Src_dTriangle->A_side >> Src_dTriangle->B_side >> Src_dTriangle->C_side;
    Src_dTriangle->Src_judge(Src_dTriangle->A_side, Src_dTriangle->B_side, Src_dTriangle->C_side);
    cout << "三角形的面積是:" << Src_dTriangle->getTriangleArea(Src_dTriangle->A_side, Src_dTriangle->B_side, Src_dTriangle->C_side) << endl;
    delete Src_dTriangle;
    Src_dTriangle = NULL;
    system("pause");
}

Triangle.h

#include <iostream>
#include <cmath>
using namespace std;
class Src_Triangle
{
public:
    double A_side;
    double B_side;
    double C_side;
    double Area;
    void Src_judge(double a, double b, double c);//定義了一個bool型別
    double getTriangleArea(double a, double b, double c);//定義了求解方法
};
void Src_Triangle::Src_judge(double a, double b, double c)
{
    if ((a + b >= c)&(b + c >= a)&(a + c >= b))
    {
        cout << "您輸入的三個數值可以構成三角形" << endl;
    }
    else
    {
        cout << "您輸入的三個數值無法構成三角形" << endl;
    }
}
double Src_Triangle::getTriangleArea(double a, double b, double c)
{
    double m;
    m = (a + b +c) / 2;
    return sqrt(m*(m - a)*(m - b)*(m - c));
    cout << "也就是說這條程式是通的" << endl;
};

、##########################################################################
使用棧的例項化方式

#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
        cout<<x<<endl;
}
void print_y()
{
        cout<<y<<endl;
}
};
int main(void)
{
    Coordinate coor;
    coor.x=10;//給資料成員進行賦值
    coor.y=1;
    coor.print_x();//運用成員函式進行列印的操作
    coor.print_y();
    system("pause");
    return 0;
}

(2)使用堆的方式例項化物件

#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
        cout<<x<<endl;
}
void print_y()
{
        cout<<y<<endl;
}
};
int main(void)
{
    Coordinate *coor=new Coordinate();
    coor->x=10;//給資料成員進行賦值
    coor->y=1;
    coor->print_x();//運用成員函式進行列印的操作
    coor->print_y();
    delete coor;
    coor=NULL;
    system("pause");
    return 0;
}

如何判斷申請記憶體是否失敗:

#include <stdlib.h>
#include <iostream>
using namespace std;
class Coordinate
{
public:
int x;
int y;
void print_x()
{
        cout<<x<<endl;
}
void print_y()
{
        cout<<y<<endl;
}
};
int main(void)
{
    Coordinate *coor=new Coordinate();
    if (NULL==coor)
    {
        cout<<"申請記憶體失敗"<<endl;//如果申請內失敗的話,就會輸出這條語句
        return 0;
    }
    coor->x=10;//給資料成員進行賦值
    coor->y=1;
    coor->print_x();//運用成員函式進行列印的操作
    coor->print_y();
    delete coor;
    coor=NULL;
    system("pause");
    return 0;
}

棧用“.”堆用“->”
如果是陣列的話,用這種方法:
這裡寫圖片描述
如果是訪問的是一個類裡面的陣列,那麼要用for語句
string的操作:
這裡寫圖片描述
這裡寫圖片描述
資料的封裝:
用函式來封裝資料成員
這裡寫圖片描述
m_下劃線有助於搜尋,str表示資料型別。
(3)

#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
    void setName(string _name)
    {
        m_strName=_name;

    }
    string getName()
    {
        return m_strName;
    }
    void setGender(string _gender)
    {
        m_strGender=_gender;

    }
    string getGender()
    {
        return m_strGender;
    }
    int getScore()//int表示他的返回值
    {

        return m_iScore;
    }
    void initScore()
    {
        m_iScore=0;
    }
    void study(int _score)
    {
        m_iScore+=_score;
    }
private:
    string m_strName;
    string m_strGender;
    int m_iScore;
};
int main(void)
{
    Student stu;
    stu.initScore();//將學分初始化
    stu.setName("David Han");
    stu.setGender("男");
    stu.study(100);
    cout<<stu.getName()<<endl<<stu.getGender()<<endl<<stu.getScore()<<endl;//這裡一定要加括號,因為加了括號才是函式
    system("pause");
    return 0;
}

程式執行結果:
這裡寫圖片描述
類外定義:
有兩種形式:1、同文件類外定義;
這裡寫圖片描述
總結一下:類外定義,其實就是在類名::然後在要定義的函式,就可以啦。
2、(常用)分檔案類外定義
這裡寫圖片描述
先定義一個頭檔案(.h檔案)然後在另外一個cpp檔案中使用。
標頭檔案裡裝的資料成員
在標頭檔案裡面定義:資料成員和宣告成員函式
注意:
h檔案要裝:
這裡寫圖片描述
在CPP檔案裡定義:具體的成員函式
舉例:
這裡寫圖片描述
值得注意的是:定義的類名,和標頭檔案的名字要一樣。
記憶體按照用途被劃分的5個區:
這裡寫圖片描述
棧區的特點就是記憶體由系統進行分配和控制。堆區,用delete來回收
定義一個類,在這個類被例項化之前是不會佔用記憶體的。物件的初始化:有兩種型別,有且僅有一次的初始化,和根據條件的初始化

這裡寫圖片描述

建構函式:(重要)作用就是初始化物件,省事。

建構函式在物件例項化的時被自動呼叫。
建構函式要與類同名,
建構函式沒有返回值。
建構函式可以進行過載。
無引數建構函式:
舉例:
這裡寫圖片描述
有引數建構函式:
舉例:
這裡寫圖片描述
當然建構函式也是可以過載的:
舉例:
這裡寫圖片描述
舉例說明,先是demo.cpp檔案

#include <iostream>
#include <stdlib.h>
#include <string>
#include "teacher.h"
using namespace std;
int main(void)
{
    teacher t1;//t1這個類是為了無參函式
    cout<<t1.getName()<<endl<<t1.getAge()<<endl;
    teacher t2("DDavid",24);//記住有參的解構函式這麼賦值,和無參的解構函式賦值方式不同。
    cout<<t2.getName()<<endl<<t2.getAge()<<endl;
    system("pause");
    return 0;
}

然後是teacher.檔案

#include <iostream>
#include <string>
using namespace std;
class teacher
{
public:
    teacher();//第一點,解構函式的賦值也是在teacher.cpp中進行的。
    teacher(string name, int age);
    void setName(string name);
    string getName();
    void setAge(int age);
    int getAge();
private:
    string m_strName;
    int m_iAge;
};

最後是teacher.cpp檔案

#include "teacher.h"//這裡只用寫這一條語句就夠了。

teacher::teacher()//無參建構函式 注意的一點的是,這裡千萬不要寫分號
{
    m_strName="David Han";
    m_iAge=23;
    cout<<"這是無參建構函式建立的"<<endl;
}
teacher::teacher(string name, int age)//有參建構函式
{
    m_strName=name;
    m_iAge=age;
    cout<<"這是有參建構函式建立的"<<endl;
}

void teacher::setName(string name)
{
    m_strName=name;
}
string teacher::getName()
{
    return m_strName;
}
void teacher::setAge(int _age)
{
    m_iAge=_age;
}
int teacher::getAge()
{
    return m_iAge;
}

執行的結果圖:
這裡寫圖片描述
初始化列表:
舉例,在上面的程式中
這裡寫圖片描述
也就是說在有參建構函式後面用冒號,然後如果是多個變數用逗號隔開。
同時,在.h檔案中可以採用上述的這種預設建構函式。
這裡寫圖片描述
執行結果:
這裡寫圖片描述
當然,也可以在demo.cpp中用這種方式進行賦值:
這裡寫圖片描述

2016年8月31日
簡單的規劃一下:從今天到9月9日,吧慕課上面的C++學完,包括遊戲開發,然後是opencv的書看完,10天的特訓,聽起來就熱血沸騰了,來吧!!
拷貝建構函式:定義格式:類名(const類名&變數名)舉例:Student (const Student &stu)特點:
1、如果沒有自定義的拷貝建構函式,則系統自動生成一個預設的拷貝建構函式。2、當採用直接初始化或複製
初始化物件時系統自動呼叫拷貝建構函式。

這裡寫圖片描述
這裡寫圖片描述
解構函式:在完成任務以後會被自動銷燬,為了釋放記憶體。定義格式:~類名()舉例:
這裡寫圖片描述
解構函式的特點:
這裡寫圖片描述
解構函式也不能過載。
這裡寫圖片描述
這裡寫圖片描述
類由成員函式和資料成員組成,如果擔心你的類和別人的類重名,那麼可以使用不同的名稱空間來加以區分。
這裡寫圖片描述
資料成員包含上面5種。
這裡寫圖片描述
成員函式的分類
這裡寫圖片描述
將上面所學到的舉例說明:

#include <iostream>
#include <string>
using namespace std;
/**
 * 定義類:Student
 * 資料成員:m_strName
 * 無參建構函式:Student()
 * 有參建構函式:Student(string _name)
 * 拷貝建構函式:Student(const Student& stu)
 * 解構函式:~Student()
 * 資料成員函式:setName(string _name)、getName()
 */
class Student
{
    public:
    //無參建構函式
    Student()
    {
        m_strName=",";
    }
    //有參建構函式
    Student(string _name)
    {
        m_strName=_name;
    }
    //拷貝建構函式
    Student(const student& stu){};
    //解構函式
    ~Student(){};

    void setName(string);
    string getName();
    private:
    string m_strName();//資料成員m_strName
    };
//成員函式setName
void Student::setName(string _name)
{
    m_strName=_name;
}
//成員函式getName
void student::getName()
{
    return m_strName;
}
int main(void)
{
    // 通過new方式例項化物件*stu
    Student *stu = new Student;
    // 更改物件的資料成員為“慕課網”
    stu->setName("慕課網");
    // 列印物件的資料成員
    cout<<stu->getName()<<endl;
    //釋放記憶體(利用堆要釋放記憶體)
    delete stu;
    stu=NUll;
    return 0;
}

物件陣列:
所謂的遍歷,就是打印出陣列當中的資訊。
物件成員:
深拷貝和淺拷貝:
總結一下:各種格式:
這裡寫圖片描述
這裡寫圖片描述
物件指標:就是一個指標,他來指向一個物件。不懂!

2016年9月1日
小技巧:選取一段程式碼,按住Ctrl+k+c就可以將所選程式碼註釋掉。
物件成員指標:不懂哦!
this指標:如果引數與資料成員同名會怎樣呢?用this指標,this指標就是指向物件自身資料的指標。用法:
這裡寫圖片描述
建議陣列成員的命名:m_(資料型別)(資料名稱)
常物件成員和常成員函式,用法:
這裡寫圖片描述
這裡寫圖片描述
物件指標和物件引用:用法:
這裡寫圖片描述
我現在開始繼承篇了
為什麼要繼承:
這裡寫圖片描述
工人這個類中,有和人這個類中一樣的屬性,那麼我們就可以用繼承的方式,達到簡化定義工人這個類,只用定義工人這個類中特有的兩個即可。(前提是人包含工人)
用法:
這裡寫圖片描述
那麼我們可以做如下定義:
這裡寫圖片描述
我們稱工人類是人類的派生類。人類是工人類的基類。或者說,工人類是子類,人類是父類。
繼承方式:1、共有繼承,格式:class A:public:B。2、保護繼承,格式:class A:protected:B。3、私有繼承,格式:class A:private:B。
三種繼承方式的差異:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
覆蓋和隱藏:
多繼承和多重繼承:
這裡寫圖片描述

多繼承的寫法:

class Worker
{
};  
class Farmer
{
};
class MigrantWork:public Worker,public Farmer
{
};

虛繼承:關鍵字virtual
通過巨集定義來解決重定義。#ifndef #define #endif
舉例:
這裡寫圖片描述
面向物件的三大特性,封裝,繼承,多型
多型:相同物件收到不同的訊息或不同物件收到相同訊息時產生不同的動作。
靜態多型VS動態多型,其中,靜態多型也叫作早繫結。動態多型也叫作晚繫結
虛擬函式:格式:
這裡寫圖片描述
動態多型存在的問題:記憶體洩漏
virtual+解構函式=虛解構函式
virtual在函式中的使用限制:1、不能修飾普通函式,2、不能修飾靜態的成員函式,3、不能修飾行內函數。
函式指標,如果一個指標指向的是函式,就是函式指標
純虛擬函式:區別:純虛擬函式沒有函式體,並且在函式後面要寫“=0”.
這裡寫圖片描述

2016年9月2日
說點感悟吧,在沒有基礎程式設計之前,覺得程式設計很神奇,然後很想學習。然後到現在是接觸和很多虛頭巴腦,似懂非懂的感念,什麼類,引用,封裝,多型,物件,虛擬函式,隱藏和覆蓋,覺得很抽象。我的繼續學下去。
抽象類:就是包含純虛擬函式的類
抽象類,不允許例項化。
抽象類的子類也是抽象類。
介面類:僅含有純虛擬函式的類就是介面類。(在類中沒有資料成員,僅有成員函式且成員成員函式都是純虛擬函式)
RTTI:執行時型別識別
使用dynamic_cast注意事項:1、只能應用於指標和引用的轉換;2、要轉換的型別中必須包含虛擬函式。3、如果轉換成功返回子類地址,轉換失敗返回NULL
typeid注意事項:1、type_id返回一個type_info的物件引用;2、如果想要通過基類指標獲得派生類的資料,基類就必須帶有虛擬函式。;3、只能獲取物件的實際型別
異常處理:對有可能發生異常的地方做出預見性的安排。關鍵字:try(嘗試)…catch(捕獲)… throw…(丟擲異常)
用法:
這裡寫圖片描述

模板

函式模板

模板,模板函式,模板類

這裡寫圖片描述
在這上面三條語句當中,int float char 這三種資料型別,但是他們具體實現的函式是一樣的,所以我們就是想吧函式作為引數傳入進去,然後讓計算機幫我們實現這三條語句的編寫

函式模板:關鍵字:template;typename;class
類模板:模板程式碼不能分離編譯

在函式名前面加上
還是上面的這個例子

這個就是函式模板
template <class T>
T max(T a,T b)
{
  return (a>b)?a:b;
}

在實際使用的時候

int ival=max(1,2);這個就是模板函式
或者

char ival=max<char>('A','B');
template <typename T>//用於宣告這個函式是一個模板
其中,T是一個型別名
typename 就是類名

template就是是一個關鍵的模板引數的

友元全域性函式,友元物件函式:關鍵字friend
友元類,就是friend+類名

A的友元可以自由的訪問A的成員函式和資料成員
B就是A的友元

class A
{
    friend void func(A*p);
    friend class B;


}

友元的注意事項:
友元的關係不可以傳遞;友元關係的單向性;友元宣告的數量和形式不受限制。友元的使用破壞了封裝性。
靜態資料成員:注意事項:靜態資料成員必須單獨初始化;靜態成員函式不能呼叫非靜態成員函式和非靜態資料成員,非靜態的資料成員可以呼叫靜態的資料成員和成員函式;靜態資料成員只有一份,並且不依賴物件而存在。

過載操作符

運算子過載:就是給原有的運算子賦予新的功能。本質就是函式過載。關鍵字:operator
舉例:一元運算子的過載:成員函式的過載,友元函式的過載 二元運算子的過載
過載操作符的使得一個自定義型別的可以像一個基本型別一樣支援加減乘除操作

STL模板

STL:C++標準模板庫:舉例說明:vetor向量:就是對陣列的封裝。
STL裡面幾乎封裝了所有常見線性資料結構

1vector 容器
2list 連結串列
3map 對映
4string 字串
5queue 佇列
6stack7set 集合
8、dequeue

在建立at/front/back這函式用於訪問陣列中的元素
at用於檢索訪問的任意位置的元素
front用於檢索頭位置的元素
back 用於檢索尾位置元素

向量的初始化方法:
這裡寫圖片描述
這裡寫圖片描述
迭代器:iterator
到這裡我第一輪的學習就算是學習完了,然後我決定就是我再學習一邊慕課網的知識,吧上面的一些概念,和一些自己跳過的知識點在學習一邊,其實也沒那麼困難。然後明天開始繼續學習C++,不學opencv,僅僅輔助學習,學習就是這樣,一心一意。弄好一個算一個。opencv linux(cenos)都是這個階段要學習的。

內部類

class AAA
{
    publicclass inner
        {
            public:
                    char name[64];  
        }
}
int main()
{
    AAA::inner a;//例項化該內部類
    return 0;
}

僅僅使用部分的空間的部分名字
using adsf::asdf;

異常

異常處理有三個關鍵字:throw、try、catch.
throw 用於丟擲
try 用於監視
catch用於剝啄

佇列篇
資料結構是指的相互之間存在一種或多種特點關係的資料元素的集合
這裡寫圖片描述
應用:自動排號機
面向物件的