bosthhe1 / cpushpush

0 stars 0 forks source link

template泛型编程 #13

Open bosthhe1 opened 1 year ago

bosthhe1 commented 1 year ago

在我们编译写代码的途中,会存在很多的场景,只是需要更换类型,不更换内部结构,如果拷贝复制的话会很麻烦,所以产生了泛型编程,泛型编程相当于一个模板,我们需要什么类型,就将泛型函数或者类,初始化成什么类型,(这里可以不用实例化,这里拥有传参的场景,可以自动推演) image

bosthhe1 commented 1 year ago

以上图为例,在我们以前的编写中,如果需要交换不同类型的值,就需要写多个函数重载函数,然后一 一对应,但是我们有了泛型函数,就可以直接传值过去,类型会自动推导(有点像auto),泛型函数的书写格式为template<class T,class TP.......>,这里面可以只定义一个,也可以定义多个,看情况而定,值得注意的是,泛型的实例化对于不同的类型,会创建不同类型的函数,所以泛型函数或者类会造成大量的函数膨胀 类型可以编译器推到,也可以指定类型传参 我们这里虽然传参为double类型,但是可以指定传int类型(显示实例化),书写形式为Add (a , b);这里我们可以看到返回值也可以用模板返回,它与auto不同,template有一点像宏替换,在函数调用的时候返回值就已经确认了,但是auto不同,auto定义出来就必须初始化,这样auto才能确定类型,auto如果推导返回值,有一种倒推的感觉,类型也不明确,所以不支持推导返回值 7ZM`COTZIJ9LQW2GTB(PLZF

bosthhe1 commented 1 year ago

但是我们可以看到在传引用的过程中,是不可以指定其他类型的,只能指定合法的类型,这里是指定调用,确认类型,不可进行隐式类型转换 image

bosthhe1 commented 1 year ago

如果我们推导的参数类型,在定义中已经存在,那么就会去调用已经定义过的函数,而不进行函数推导,当我们已经定义了一个int类型的函数,template推导也为int,系统就会调用已经定义的函数,而不去调用自动推导 image

bosthhe1 commented 1 year ago
template<class T>//类模板(类模板和class Stack是一个类整体,相当于连体的)
//template和class中间不允许写其他东西,因为他们是一个整体,不能分开,中间写了其他东西,class会找不到类模板
class Stack
{
public:
    Stack(int capacity = 4)
        :_top(0)
        , _capacity(capacity)
    {
          _a = new T[capacity];
    }
    ~Stack()
    {
        delete[] _a;
        _a = nullptr;
        _top = 0;
    }
    void Push_Back(T a);
private:
    T *_a;
    int _top;
    int _capacity;
};
//这里相当于出了类,跳到了全局,所以需要重新指定,和class一样,中间不能写其他的东西,必须连着写
template<class T>//这里的模板就是为了指定类
void Stack<T>::Push_Back(T a)//这个需要注意函数定义的方式,不仅要指定类域,也要指定模板,这个函数和上面的模板为一体
{
     //..........
}
template<class T>//这里需要重新指定类模板,因为上面函数把这个函数隔开了,这个函数
void Stack<T>::Push_Head(T a)//这个也需要指定类型,同时指定类模板,他们为一体
{
    //....
}
int main()
{
    Stack<int> d1(4);// 必须手动实例化类模板(因为这里不存在实参传给形参的场景)
    return 0;
}
bosthhe1 commented 1 year ago

类模板是一个类家族,模板类是通过类模板实例化的具体类