C++遠征_模板篇

模板篇

友元函數

關鍵字:friend

友元全局函數

友元成員函數

class Coordinate
{
    friend void printXY(Coordinate &c);
};

友元,可以訪問對象中的 privateprotected 數據成員

雖然方便數據的直接訪問,但是也破壞了封裝性。不建議使用友元

友元類

class Circle;
class Coordinate{
    friend Circle;
};

Circle 對象就可以任意訪問 Coordinate 對象的 數據成員 和 成員函數

關於友元的注意事項

  • 友元關係不可傳遞
  • 友元關係的單向性
  • 友元聲明的形式及數量不受限制

友元只是封裝的補充,不建議

注:由於編譯器不同,友元類有兩種寫法。1、friend class 類名; 2、friend 類名;

static

靜態數據成員

靜態成員函數

靜態數據成員一般不在構造函數中實例化,一般單獨進行

class Tank{
public:
    Tank() {s_iCount++;}
    ~Tank() {s_iCount--;}
    static int s_iCount;
    static int getCount();
};
int Tank::s_iCount = 0;

靜態數據和函數的訪問:(共享)

int main(void)
{
    cout << Tank::getCount() << endl;
    cout << Tank::s_iCount << endl;
    Tank tank;
    cout << tank.getCount() << endl;
    cout << tank.s_iCount << endl;
    return 0;
}

從this 指針談靜態成員函數

class Tank
{
public:
    void fire();
    static int getCount();
private:
    string m_strCode;
    static int s_iCount;
}


// 實際上,fire函數會隱式傳入一個 this 指針
void fire(Tank *this) {
    this->m_strCode = "01";
    s_iCount = 0;
}

// 靜態成員函數則不會 隱式 傳入一個 this 指針
static int getCount() {
    m_strCode = "01"; // 報錯
    return s_iCount;
}

注意事項

  • 靜態數據成員必須單獨初始化
  • 靜態成員函數不能調用非靜態成員函數和非靜態數據成員
  • 靜態數據成員只有一份,且不依賴對象而存在,sizeof 不計算
  • 靜態成員函數無法加 const,這與 this 指針的本質是相符合的

運算符重載

給原有的運算符賦予新的功能

如:給 + 號重載,使其能夠實現兩個字符串拼接

運算符重載的本質:函數重載

關鍵字:operator

一元運算符重載

-(負號)的重載

  • 友元函數重載

    class Coordinate{
      friend Coordinate& operator-(Coordinate &coor);
    };
    
    // 定義
    Coordinate& operator-(Coordinate &coor)
    {
        coor.m_iX = -coor.m_iX;
        coor.m_iY = -coor.m_iY;
        return *this;
    }
    
    // 使用
    Coordinate coor1(3,5);
    -coor1; // operator-(coor1);
    
    
  • 成員函數重載

    class Coordinate{
      public:
        Coordinate& operator-();
    };
    
    // 定義
    Coordinate& Coordinate::operator-()
    {
        m_iX = -m_iX;
        m_iY = -m_iY;
        return *this;
    }
    
    // 使用
    Coordinate coor1(3,5);
    -coor1; // coor1.operator-();
    
    

++符號的重載

  • 前置++符號重載

    class Coordinate{
        Coordinate& operator++(); // 前置++
        
    };
    
    // 定義
    Coordinate& Coordinate::operator++(){
        m_iX++;
        m_iY++;
        return *this;
    }
    
    // 使用
    Coordinate coor1(3,5);
    ++coor1; // coor1.operator++();
    
  • 後置++符號重載

    Coordinate operator++(int); // 後置++
    
    // 定義
    Coordinate operator++(int){
    	Coordinate old(*this);
        m_iX++;
        m_iY++;
        return old;
    }
    
    // 使用
    coor1++; // coor1.operator++(0);
    
    

二元運算符重載

+號運算符

  • 成員函數重載:

    class Coordinate{
    public:
        Coordinate operator+(const Coordinate &coor);
    };
    
    // 定義
    Coordinate operator+(const Coordinate &coor)
    {
        Coordinate temp;
        temp.m_iX = this->m_iX + coor.m_iX;
        temp.m_iY = this->m_iY + coor.m_iY;
        return temp;
    }
    
    // 使用
    Coordinate coor1(3,5);
    Coordinate coor2(4,7);
    coor3 = coor1 + coor2; // coor1.operator+(coor2);
    
    
  • 友元函數重載:

    class Coordinate{
      friend Coordinate operator+(const Coordinate &c1,const Coordinate &c2);
    };
    
    // 定義
    Coordinate operator+(const Coordinate &c1,const Coordinate &c2){
        Coordinate temp;
        temp.m_iX = c1.m_iX + c2.m_iX;
        temp.m_iY = c1.m_iY + c2.m_iY;
        return temp;
    }
    
    // 使用
    coor3 = coor1 + coor2; // operator+(coor1,coor2);
    
    

<< 運算符:

  • 友元函數重載:

    class Coordinate{
        friend ostream& operator<<(ostream &out,const Coordinate &coor);
    };
    
    
    // 定義
    ostream &operator<<(ostream &out, const Coordinate &coor){
    	out << coor.m_iX << "," << coor.m_iY;
        return out;
    }
    
    // 使用
    cout << coor; // operator<<(cout,coor);
    
    
  • **成員函數重載:**和this 的本質有關, << 運算符必須傳入 ostream,所以不能重載

[] 運算符

  • 成員函數

    class Coordinate{
        public:
        int operator[](int index);
    };
    
    
    // 定義
    int Coordinate::operator [](int index) {
        if(index == 0) {
            return m_iX;
        }
        if(index == 1) {
            return m_iY;
        }
    }
    // 使用
    Coordinate coor(3,5);
    cout << coor[0]; // coor.operator[](0);
    cout << coor[1]; // coor.operator[](1);
    
  • **友元函數重載:**和 this 本質有關, [] 運算符必須傳入 索引 值,所以不能重載

函數模板

關鍵字: template typename class

template <class T>
T max(T a,T b) {
    return (a > b) ? a : b;
}

// 使用
int ival = max(100,99);
char cval = max<char>('A','B');


template<typename T>
void swap(T &a,T &b) {
    T tmp = a;
    a = b;
    b = tmp;
}

// 使用
int x = 20,y = 30;
swap<int>(x,y);

**注意:**如果只有函數模板 而沒有對其進行調用,編譯後是不會產生代碼邏輯的,因爲類型不確定,並不知道產生什麼具體類型的函數

變量作爲模板參數

template<int size>
void display()
{
    cout << size << endl;
}

display<10>();

多參數函數模板

template <typename T,typename C>
void display(T a,C b) {
    cout << a << " " << b << endl;
}

// 使用
int a = 1024;
string str = "Hello world!";
display<int,string>(a,str);

typename 和 class 意義一樣,可以混用

函數模板與重載

template<typename T>
void display(T a);

template<typename T>
void display(T a,T b);

template<typename T,int size>
void display(T a);

類模板

template<class T>
class MyArray{
    T *m_pArr;
};

template<class T>
    void MyArray<T>::display(){
        ...
    }

// 使用
MyArray<int> arr;
arr.display();

注意:模板代碼不能分離編譯

C++標準模板 STL

STL:Standard Template Lib

vector 向量

本質:對數組的封裝

動態增加或者減小數組長度

特點:讀取能在常數時間完成

vector 初始化:

在這裏插入圖片描述

vector<int> ivec1;
vector<int> ivec2(ivec1);

vector<string> svec1;
vector<string> svec2(ivec);

vector<int> ivec4(10,-1);
vector<string> svec(10, "hi!");

vector 常用函數:

在這裏插入圖片描述

vector 使用:

vector<int> vec;
vec.push_back(10);
vec.pop_back();
cout << vec.size() << endl;

for(int k = 0;k < vec.size();k++) {
    cout << vec[k] << endl;
}

迭代器:iterator

vector vec;
vec.push_back("hello");
vector<string>::iterator citer = vec.begin();
for(;citer != vec.end();citer++) {
	cout << *citer << endl;
}

list:鏈表

特點:數據插入速度快

map:映射

map<int,string> m;
pair<int,string> p1(10,"shanghai");
pair<int,string> p2(20,"beijing");

m.insert(p1);
m.insert(p2);

cout << m[10] << endl;
cout << m[20] << endl;

pair<int,string> p1("S","shanghai");
pair<int,string> p2("B","beijing");
m.insert(p1);
m.insert(p2);
cout << m["S"] << endl;
cout << m["B"] << endl;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章