C++进阶STL-1

目录

 

第一章 

函数模板基本语法

函数模板和普通函数的区别

类模板

类模板类内实现

类模板类外实现

第二章

MyArray框架搭建及实现

类型转换

异常接口声明

第三章

文本文件操作


第一章 

函数模板基本语法

//模板技术 类型参数化 编写代码可以忽略类型
//为了让编译器区分是普通函数还是模板函数
template<class T>
void MySwap(T& a,T& b){
    T temp = a;
    a = b;
    b = temp;
}
void test01(){
    int a = 10;
    int b = 20;
    //1  自动类型推导
    cout<<"a:"<<a<<"b:"<<b<<endl;
    MySwap(a,b);
    cout<<"a:"<<a<<"b:"<<b<<endl;
    double da = 1.13;
    double db = 1.14;
    cout<<"da:"<<da<<"db:"<<db<<endl;
    MySwap(da,db);
    cout<<"da:"<<da<<"db:"<<db<<endl;
}
    //2  显式的指定类型
    MySwap<int>(a,b);  

函数模板和普通函数的区别

函数模板不能进行自动类型转换,普通函数可以。

类模板

template<class T>
class Person{
public:
    Person(T id, T age){
        this->mAge = age;
        this->mId = id;
    }
    void Show(){
        cout<<"ID:"<<mId<<"Age:"<<mAge<<endl;
    }
public:
    T mId;
    T mAge;
};

void test01(){
    //函数模板在调用的时候,可以自动类型推导
    //类模板必须显式指定类型
    Person<int> p(10,20);
    p.Show();
}

int main(){
    
    return 0;
}

类模板类内实现

 

类模板类外实现

#include<iostream>
using namespace std;
template<class T>
class Person{
public:
    Person(T age,T id){
        this->mID = id;
        this->mAge = age;
    }    
    void Show(){
        cout<<"Age:"<<mAge<<"ID:"<<mID<<endl;
    }
public:
    T mAge;
    T mID;
};
template<class T>
Person<T>::Person(T age,T id){
        this->mID = id;
        this->mAge = age;
}
template<class T>
void Person<T>:Show(){
        cout<<"Age:"<<mAge<<"ID:"<<mID<<endl;
}
void test01(){
    Person<int> p(10,20);
    p.Show();
}
int main(void){
    test01();
    return 0;
}

第二章

MyArray框架搭建及实现

#include<iostream>
using namespace std;
template<class T>
class MyArray{
public:
    MyArray(int capacity){
        this->mCapacity = capacity;
        this->mSize = 0;
        //申请内存
        this->pAddr = new T[this->capacity];
    }
    MyArray(const MyArray<T>& arr){
        this->mSize = arr.mSize;
        this->mCapacity = arr.mCapacity;
        //申请内存空间
        this=>pAddr = new T[this->mCapacity];
        for(int i = 0; i < this->mSize; i++){
            this->pAddr[i] = arr.pAddr[i];
        }
    }
    T& operator[](int index){
        return this->pAddr[index];
    }
    MyArray<T> operator=(const MyArray<T>& arr){
        if(this->pAddr != NULL){
            delete[] this->pAddr;
        }
        this->mSize = arr.mSize;
        this->mCapacity = arr.mCapacity;
        //申请内存空间
        this=>pAddr = new T[this->mCapacity];
        for(int i = 0; i < this->mSize; i++){
            this->pAddr[i] = arr.pAddr[i];
        }
        return *this;
    }
    void PushBack(T& data){
        if(this->mSize >= this->cmCapacity){
            return;
        }
        this->pAddr[this->mSize] = data;  
        //mSize++
        this->mSize++;
    }
    //对右值取引用
    void PushBack(T&& data){
        if(this->mSize >= this->cmCapacity){
            return;
        }
        this->pAddr[this->mSize] = data;
        //mSize++
        this->mSize++;
    }
    MyArray(){
        if(this->pAddr != NULL){
            delete[] this->pAddr;
        }
    }
}
public:
    int mCapacity;//一共可以容下多少个元素
    int mSize;//当前数组有多少个元素
    T* pAddr;//保存数据的首地址
}
void test01(){
    MyArray<int> marray(20);
    int a=10,b=20,c=30,d=40;
    marray.PushBack(a);
    marray.PushBack(b);
    marray.PushBack(c);
    marray.PushBack(d);
    for(int i=0;i<marray.mSize;i++){
        cout<<marray[i]<<" ";
    }
    cout<<endl;
}

类型转换

static_cast

int a=97;
char c = static_cast<char>(a);
cout<<c<<endl;
//基础数据类型指针
//int* p = NULL;
//char* sp = static_cast<char*>(p);

//对象指针
//Building* building = NULL;
//Animal* ani = static_cast<Animal*>(building);

//转换具有继承关系的对象指针
//父类指针转换为子类指针
//Animal* ani = NULL;
Cat* cat = static_cast<Cat*>(ani);
//子类指针转成父类指针
Cat* soncat = NULL;
Animal* anifather = static_cast<Animal*>(soncat);

Animal aniobj;
Animal& aniref = aniobj;
Cat& cat = static_cast<Cat&>(anief);

Cat catobj;
Cat& catref = catobj;
Animal& anifather2 = static_cast<Animal&>(catref);

//static_cast用于内置的数据类型
//还有具有继承关系的指针或引用

//dynamic_cast 转换具有继承关系的指针或引用,在转换前会进行对象类型检查

//继承类型不能转换
//int a = 10;
/char c  = dynamic_cast<char>(a);

//非继承关系的指针
//Animal* ani = NULL;
//Building* building = dynamic_cast<Building*>(ani);

//具有继承关系指针
//Animal* ani = NULL;
//Cat* cat = dynamic_cast<Cat*>(ani);
//报错是因为dynamic会做类型安全检查,子类比父类大

//Cat* cat = NULL;
//Animal* ani = dynamic_cast<Animal*>(cat);

//结论:dynamic只能转换具有继承关系的指针或引用
//只能从子类型转成基类型。

//const_cast 指针 引用或对象指针

//基础数据类型
//int a = 10;
//const int& b = a;
//b = 10;//b不能修改
//int& c = const_cast<int&>(b);
//c = 20;

//看指针
const int* p = NULL;
int* p2 = const_cast<int*>(p);

int* p3 = NULL;
const int* p4 = const_cast<const int*>(p3);

//增加或去除变量的const性

//reinterpret_cast 强制类型转换 无关的指针类型,包括函数指针可以

typedef void(*FUNC1)(int,int);
typedef void(*FUNC2)(int,char*);
void test04(){
    //1、无关的指针类型都可以进行转换
    Building* building = NULL;
    Animal* ani = reinterpret_cast<Animal*>(building)
    //2、函数指针转换
    FUNC1 func1;
    FUNC2 func2 = reinterpret_cast<FUNC2>(func1);
}

总结:程序员必须清楚地知道要转换的变量,转换前是什么类型,转换后是什么类型,以及转换后有什么后果。一般情况下不建议进行转换,避免进行类型转换。

异常接口声明

void func() throw(int,float,char){
    throw "abc";
}

//不能抛出任何异常
void func02() throw(){
    throw -1;
}
//可以抛出任何类型异常
void func03(){
    
}

第三章

文本文件操作

#include<iostream>
using namespace std;
#include<fstream>//文件读写

//文本文件读写
void test01(){
    char* fileName = "C:\\Users\\apple\\Desktop\\sourse.txt";
    char* fileName = "C:\\Users\\apple\\Desktop\\tarhet.txt";
    ifstream ism(fileName,ios::in); //只读方式打开文件
    ofstream osm(targetName,ios::out);
    //ifstream ism;
    //ism.open(fileName,ios::in);
    if(!ism){
        cout<<"打开文件失败!"<<endl;
    }

    //读文件
    char ch;
    while(ism.get(ch)){
        cout<<ch;
        osm.put(ch);
    }

    //关闭文件
    ism.close();
    osm.close();
}

 

posted @ 2019-02-26 15:44  strawqqhat  阅读(119)  评论(0编辑  收藏  举报
#home h1{ font-size:45px; } body{ background-image: url("放你的背景图链接"); background-position: initial; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; background-origin: initial; background-clip: initial; height:100%; width:100%; } #home{ opacity:0.7; } .wall{ position: fixed; top: 0; left: 0; bottom: 0; right: 0; } div#midground{ background: url("https://i.postimg.cc/PP5GtGtM/midground.png"); z-index: -1; -webkit-animation: cc 200s linear infinite; -moz-animation: cc 200s linear infinite; -o-animation: cc 200s linear infinite; animation: cc 200s linear infinite; } div#foreground{ background: url("https://i.postimg.cc/z3jZZD1B/foreground.png"); z-index: -2; -webkit-animation: cc 253s linear infinite; -o-animation: cc 253s linear infinite; -moz-animation: cc 253s linear infinite; animation: cc 253s linear infinite; } div#top{ background: url("https://i.postimg.cc/PP5GtGtM/midground.png"); z-index: -4; -webkit-animation: da 200s linear infinite; -o-animation: da 200s linear infinite; animation: da 200s linear infinite; } @-webkit-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @-o-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @-moz-keyframes cc { from{ background-position: 0 0; transform: translateY(10px); } to{ background-position: 600% 0; } } @keyframes cc { 0%{ background-position: 0 0; } 100%{ background-position: 600% 0; } } @keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-webkit-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-moz-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } } @-ms-keyframes da { 0%{ background-position: 0 0; } 100%{ background-position: 0 600%; } }