4. STL编程四

1. 类模板的默认参数规则:

#include <iostream>
using namespace std;

/*
//类模板,不调用不编译(函数);变量还是规范
template<class T = int>    //即使参数默认,调用的时候还是要指明类型
class myclass
{
public:
    T a;
    T b;

    T add()
    {
        return a + b;
    }

};

int main()
{
    myclass<int> my;
    my.a = 10;
    my.b = 20;
    my.add();

    system("pause");
    return 0;
}
*/

template<class T1, class T2 = double, class T3 = char>    //默认参数,原则上都放在右边
class myclassT
{
public:

};

int main()
{
    myclassT<int> my1;        //<>无论如何都不能省略,
    //有默认参数原则上可以省略;如果中间出现一个没有省略,需输入若干参数,覆盖那个位置

    system("pause");
    return 0;
}

 2. 类模板的嵌套:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

/*
//类的怀孕现象
class my
{
public:
    class zi    //嵌套类
    {

    };

    zi z1;
};
*/

template<class T>
class myT
{
public:
    template<class T>    //嵌套类模板
    class ziT
    {
        T a;
    public:
        void seta(T t)
        {
            a = t;
        }

        T geta()
        {
            return a;
        }
    };

    ziT<int>    my1;      //无论外部什么类型,始终都是int
    ziT<T>      my2;      //外部什么类型,内部也是该类型
    vector<T>   myv;
    list<T>     myx;
};

int main()
{
    myT<double> d1;

    system("pause");
    return 0;
}

3. 模板参数的嵌套:

#include <iostream>
#include <vector>
#include <list>
#include <string>
using namespace std;

/*
int main()
{
    vector<int>                        myint1;
    vector< vector<int> >              myint2;    //二维数组
    vector< vector< vector<int> > >    myint3;    //三位数组

    system("pause");
    return 0;
}
*/

template<class T>
class men
{
public:
    men()
    {
        
    }
    ~men()
    {

    }
    T getAge()
    {
        return age;
    }
    T getName()
    {
        return name;
    }
    void setAge(T && a)
    {
        age = a;
    }
    void setName(T & n)
    {
        name = n;
    }

private:
    T name;
    T age;

};

template<template<class T>class T1>        //此时 T1 <==> men
class people
{
public:
    T1<int> s1;            //T1<int> <==> men<int>
    T1<string> s2;

    people()
    {
        
    }
    ~people()
    {

    }

};

int main()
{
    people<men> chinese;

    chinese.s1.setAge(50);
    cout << chinese.s1.getAge() << endl;

    chinese.s2.setAge("中国人");
    cout << chinese.s2.getAge() << endl;

    system("pause");
    return 0;
}

    

4. 模板与友元函数:

  4.1 类模板 与 友元函数模板:

#include <iostream>
using namespace std;

template<class T>
class myclass
{
public:
    myclass(T m, T n):a(m),b(n)
    {
    }
    ~myclass()
    {

    }
private:
    T a;
    T b;

    template<class T>
    friend void show(myclass<T> my);        //友元函数声明,声明也必须带上template

    friend void show(myclass<double> my);   //明确类型的调用
};

template<class T>
void show(myclass<T> my)
{
    cout << my.a << " " << my.b << endl;
}

void show(myclass<double> my)
{

}

int main()
{
    myclass<int> my1(29, 39);
    show(my1);

    system("pause");
    return 0;
}

    

  4.2 类模板 与 友元类模板:

#include <iostream>
using namespace std;

template<class T> class showit;    //先声明showit类,引用友元类,创建引用或指针,唯独不能创建对象

template<class T>
class myclass
{
public:
    myclass(T m, T n) :a(m), b(n)
    {
    }

private:
    T a; 
    T b;

    friend class showit<T>;    //声明友元类,该类为一个类模板
};

template<class T>
class showit
{
public:
    myclass<T> *p;
    void set(T a, T b)
    {
        p = new myclass<T>(a, b);
        cout << p->a << " " << p->b << endl;
    }
};

int main()
{
    showit<int> showit1;
    showit1.set(99, 87);

    system("pause");
    return 0;
}

    

5. 类模板与static静态成员:

#include <iostream>
using namespace std;

template<class T>
class myclass
{
public:
    //静态成员不属于这个类,它在静态区,不能将其值设定在内部,
    //static int num = 0;    //error C2864: “myclass<T>::num”: 带有类内初始值设定项的静态 数据成员 必须具有不可变的常量整型
    static int num;

    myclass()
    {
        num += 1;
    }
    ~myclass()
    {
        num -= 1;
    }
    void show()
    {
        cout << "num=" << num << endl;
        cout << typeid(*this).name() << endl;
    }
};

template<class T>
int myclass<T>::num = 0;

//static成员,每个类型实例化都会创建一个变量;类型一致,共享;类型不一致,私有。
int main()
{
    myclass<int> *p1 = new myclass<int>[10];    //调用10次构造函数
    myclass<int> *p3 = new myclass<int>[10];
    p1->show();        //20    类型一致,共享

    myclass<double> *p2 = new myclass<double>[19];    
    p2->show();        //19    类型不一致

    system("pause");
    return 0;
}

    

6. 类模板与static静态成员函数:

  6.1 static静态成员函数没有this指针:

#include <iostream>
using namespace std;

template<class T>
class myclass
{
public:
    void go1()
    {
        this;
    }
    static void go2()    //静态成员函数的指针类型不一样,没有this指针
    {
        
    }
};

int main()
{
    auto fun1 = &myclass<int>::go1;
    auto fun2 = &myclass<int>::go2;

    //成员函数与静态成员函数最大区别,函数指针类型不一样,静态成员函数没有this指针
    cout << typeid(fun1).name() << endl;
    cout << typeid(fun2).name() << endl;

    myclass<char> mych;

    system("pause");
    return 0;
}

    

  6.2 静态成员函数无需创建对象就可调用:

#include <iostream>
using namespace std;

template<class T>
class myclass
{
public:
    void go1()
    {
        cout << "go1" << endl;
    }
    static void go2()    //静态成员函数的指针类型不一样,没有this指针
    {
        cout << "go2" << endl;
    }
};

int main()
{
    myclass<int>::go2();    //静态成员函数,无需创建对象就可以直接调用(既可以创建对象来调用,也可以不创建对象来调用)
    //myclass<int>::go1();

    myclass<int> my1;
    my1.go1();
    my1.go2();

    system("pause");
    return 0;
}

    

 

posted @ 2018-11-21 23:17  博观&约取  阅读(188)  评论(0编辑  收藏  举报