zoukankan      html  css  js  c++  java
  • 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();
    }
  • 相关阅读:
    Miller_Rabin
    无向图必经点、必经边的相关问题
    无向图的连通性与相关问题
    HNOI2012 矿场搭建 v-DCC缩点+分类讨论
    冗余路径 Redundant Paths e-DCC缩点
    poj1275 Cashier Employment 差分约束
    csp2019游记
    picxivic爬虫
    水贴自动机
    三维生命游戏
  • 原文地址:https://www.cnblogs.com/strawqqhat/p/10602252.html
Copyright © 2011-2022 走看看