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;
发布了51 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_39446719/article/details/89891690