最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++函數(shù)模板與類模板相同與不同介紹

 更新時(shí)間:2022年08月16日 10:24:53   作者:lhb2998658795  
C++語言的模板技術(shù)包括函數(shù)模板和類模板,模板技術(shù)是一種代碼重用技術(shù),函數(shù)和類是C++語言中兩種主要的重用代碼形式,這篇文章主要介紹了C++函數(shù)模板和類模板,需要的朋友可以參考下

1.模板 

1.1何為模板

即模子,生成器。

1.2C++的模板的形式有兩種

函數(shù)模板與類模板。

1.3如何定義一個(gè)函數(shù)模板

就像定義函數(shù)一樣,定義一個(gè)函數(shù)模板,把函數(shù)中類型抽象出來,

同時(shí)告訴編譯器下面的函數(shù)是一個(gè)函數(shù)模子或函數(shù)生成器。

1.4語法形式

template + <class T1, class T2 = double, class T3 = int ....>
//模板頭中的類型參數(shù)列表也可以有默認(rèn)值。
T add(T a, T b)
{
    return a + b;
}

1.5模板的編譯機(jī)制

1.編譯器并不是把模板處理成能夠處理任何類型的函數(shù),而是一個(gè)函數(shù)或類的生成器。

2.函數(shù)模板通過具體類型產(chǎn)生不同的函數(shù)(產(chǎn)生了模板函數(shù))

3.編譯器會對函數(shù)模板進(jìn)行兩次編譯,第一次在聲明的地方對模板本身進(jìn)行編譯,在調(diào)用的地方對參數(shù)替換后的代碼進(jìn)行編譯使用函數(shù)模板與真正的函數(shù),誰的調(diào)用效率高呢?當(dāng)然是真正的函數(shù),因?yàn)楹瘮?shù)模板還需要編譯器進(jìn)行翻譯一遍才能調(diào)用。所以現(xiàn)開發(fā)中并不一定要把所有函數(shù)你都要定義成函數(shù)模板,所以類型替換之后的函數(shù)模板就成了一個(gè)函數(shù)實(shí)例了,這樣才能調(diào)用。

代碼實(shí)例:

#include <iostream>
using namespace std;
template <class T>
T my_add(T a, T b)
{
    return a + b;
}
int main()
{
    my_add<int>(10,20);
    my_add<float>(3.14f,5.21f);
    my_add<double>(5.21,3.14);
    return 0;
}

2.函數(shù)模板

2.1調(diào)用方式

顯式調(diào)用:函數(shù)名后使用<>尖括號指定具體參數(shù)調(diào)用。

using namespace std;
template <class T>
T my_add(T a, T b)
{
    return a + b;
}
int main()
{
    my_add<int>(10,20);
    my_add<float>(3.14f,5.21f);
    my_add<double>(5.21,3.14);
    return 0;
}

隱式調(diào)用:由編譯器自動(dòng)根據(jù)參數(shù)推導(dǎo)參數(shù)類型再調(diào)用。

#include <iostream>
using namespace std;
template <class T>
T my_add(T a, T b)
{
    return a + b;
}
int main()
{
    my_add(10,20);
    my_add(3.14f,5.21f);
    my_add(5.21,3.14);
    return 0;
}

2.2函數(shù)模板的特化與調(diào)用優(yōu)先級

當(dāng)只有基礎(chǔ)模板和特化模板時(shí)。

#include <iostream>
using namespace std;
template <class T>
T my_add(T a,T b)
{
    cout<<"這是一個(gè)基礎(chǔ)模板"<<endl;
    return a+b;
}
template <class T>
T my_add(int a,int b)
{
    cout<<"這是一個(gè)特化模板"<<endl;
    return a+b;
}
int main()
{
    cout<<my_add(10,20)<<endl;
    return 0;
}

結(jié)果圖:

當(dāng)只有基礎(chǔ)模板和特化模板時(shí),隱式調(diào)用基礎(chǔ)模板。

當(dāng)有基礎(chǔ)模板和特化模板,還有實(shí)例時(shí)候。

#include <iostream>
using namespace std;
template <class T>
T my_add(T a,T b)
{
    cout<<"這是一個(gè)基礎(chǔ)模板"<<endl;
    return a+b;
}
template <class T>
T my_add(int a,int b)
{
    cout<<"這是一個(gè)特化模板"<<endl;
    return a+b;
}
int my_add(int a,int b)
{
    cout<<"這是一個(gè)實(shí)例"<<endl;
    return a+b;
}
int main()
{
    cout<<my_add(10,20)<<endl;
    return 0;
}

結(jié)果圖:

當(dāng)有基礎(chǔ)模板和特化模板,還有實(shí)例時(shí)候,隱式調(diào)用用實(shí)例。

當(dāng)有基礎(chǔ)模板和特化模板,還有實(shí)例時(shí)候,顯示調(diào)用

#include <iostream>
using namespace std;
template <class T>
T my_add(T a,T b)
{
    cout<<"這是一個(gè)基礎(chǔ)模板"<<endl;
    return a+b;
}
template <class T>
T my_add(int a,int b)
{
    cout<<"這是一個(gè)特化模板"<<endl;
    return a+b;
}
int my_add(int a,int b)
{
    cout<<"這是一個(gè)實(shí)例"<<endl;
    return a+b;
}
int main()
{
   cout<<my_add<int>(10,20)<<endl;
    return 0;
}

結(jié)果圖:

當(dāng)有基礎(chǔ)模板和特化模板,還有實(shí)例時(shí)候,顯示調(diào)用用特化模板。

總結(jié):

當(dāng)有函數(shù)實(shí)例時(shí):隱式調(diào)用將直接調(diào)用函數(shù)實(shí)例。

如果沒有函數(shù)實(shí)例時(shí),隱式調(diào)用將直接調(diào)用函數(shù)模板的基礎(chǔ)模板。

如果使用顯示調(diào)用,當(dāng)優(yōu)先調(diào)用特化的與類型匹配的函數(shù)模板。

3.可變參函數(shù)模板

3.1概念

所謂的可變參模板是指類型參數(shù)為一一個(gè)可變是類型,這個(gè)類型使用class...來修飾。

3.2代碼實(shí)現(xiàn)(實(shí)現(xiàn)一個(gè)c中的printf的函數(shù))

#include <iostream>
using namespace std;
void printf()
{
}
template <class Firstarg,class... Arg>
void printf(Firstarg firstarg, Arg... arg)
{
    cout<<firstarg;
    printf(arg...);
}
int main()
{
    printf("lisi","cc");
    return 0;
}

結(jié)果圖:

4.類模板

4.1類模板的定義形式

注意:在使用類模板時(shí),不存在編譯推導(dǎo)類型,必須手動(dòng)指定具體類型。

template <class T1, class T2, class T3 ...> 
//class修飾符也可使用typename來修飾。
class + 類名
{
    //類模板的模板體。
    private:
        //類模板中的屬性。
    public:
        //類中的方法
    protected:
};

4.2代碼實(shí)例

#include <iostream>
using namespace std;
template <class T1,class T2>
class A
{
    T1 name;
    T2 age;
public:
    A(T1 name,T2 age)
    {
        this->age=age;
        this->name=name;
    }
    void show_info()
    {
        cout<<"name="<<name<<",age="<<age<<endl;
    }
};
int main()
{
//    A<string,int> a("lisi",20);
//    a.show_info();
    A<string,int>* a=new A<string,int>("lisi",20);
    a->show_info();
    return 0;
}

結(jié)果圖:

5.類模板中的特殊屬性的初始化方式及繼承與多態(tài)

5.1代碼實(shí)例

#include <iostream>
using namespace std;
template  <class T1,class T2>
class A
{
    T1 name;
    T2 age;
public:
    A(T1 name,T2 age)
    {
        this->name=name;
        this->age=age;
    }
    virtual void show_info()
    {
        cout<<"name="<<this->name<<",age"<<age<<endl;
    }
    void set_name(T1 name)
    {
        this->name=name;
    }
    T1 get_name()
    {
        return  this->name;
    }
    void set_age(T2 age)
    {
        this->age=age;
    }
    T2 get_age()
    {
        return this->age;
    }
};
template <class T1,class T2,class T3>
class B:public A<T1,T2>
{
    const int id;
    static int count;
public:
    B(T1 name,T2 age,T3 _id):id(_id),A<T1,T2>(name,age)
    {
    }
    void show_info()
    {
        cout<<"id="<<this->id<<",name="<<this->get_name()<<",age"<<this->get_age()<<endl;
    }
};
int main()
{
    //1.棧上
    B<string,int,int> b("lisi",20,1001);
    b.show_info();
    //2.堆上
    B<string,int,int>* b1=new B<string,int,int>("zhangsan",29,1002);
    b1->show_info();
    //3.實(shí)現(xiàn)多態(tài)
    A<string,int>* a=new B<string,int,int>("wangwu",50,1003);
    a->show_info();
    return 0;
}

結(jié)果圖:

5.2使用類模板去實(shí)現(xiàn)一個(gè)數(shù)據(jù)結(jié)構(gòu)

實(shí)現(xiàn)一個(gè)順序棧模板

首先我們使用一下多文件編程,類似于c的那種,我們會發(fā)現(xiàn)問題如下:

main.cpp文件:

#include <iostream>
#include "socket.h"
using namespace std;
int main()
{
    socket<int> s(2);
    return 0;
}

stack.h文件:

#ifndef SOCKET_H
#define SOCKET_H
using namespace std;
#include <iostream>
template <class T>
class socket
{
    T* m_date;
    int len;
    int max_size;
public:
    //構(gòu)造
    socket(int _len);
    //析構(gòu)
    ~socket();
    //入棧
    void push(const socket& other);
    //出棧
    void out();
    //獲取棧頂?shù)闹?
    T get_out();
    //判斷是否為空
    bool is_empty();
};
#endif // SOCKET_H

stack.cpp文件:

#include "socket.h"
template <class T>
socket<T>::socket(int _max_size)
{
    this->m_date=new T[len];
    this->len=0;
    this->max_size=_max_size;
}

結(jié)果圖:

結(jié)果分析:如圖所以,結(jié)果告訴我們無法連接到構(gòu)造函數(shù),這是由于我們使用的是模板類,模板類需要被編譯兩次,如果我們像這樣把stack.cpp和stack.h分開寫的話,stack.cpp里面的模板只被編譯了一次,所以我們無法連接到構(gòu)造函數(shù)。

使分文件編程的方式實(shí)現(xiàn)一個(gè)模板棧:

在C++分文件編程時(shí),在業(yè)內(nèi)常用的一種文件標(biāo)準(zhǔn)是后綴為.hpp的模板文件。

代碼實(shí)現(xiàn):

stack.cpp文件:

#ifndef STACK_HPP
#define STACK_HPP
using namespace std;
#include <iostream>
template  <class T>
class Stack
{
    T* my_data;
    int len;
    int max_size;
public:
    //構(gòu)造函數(shù)
    Stack(int _max_size);
    //析構(gòu)函數(shù)
    ~Stack();
    //入棧
    void push(const int& other);
    //出棧
    void out_data();
    //獲取棧頂?shù)闹?
    T get_data();
    //判斷是否為空
    bool is_empty();
};
#endif // STACK_HPP
template <class T>
Stack<T>::Stack(int _max_size)
{
    this->my_data=new int[_max_size];
    this->len=0;
    this->max_size=_max_size;
}
template <class T>
Stack<T>::~Stack()
{
    if(this->my_data!=nullptr){
        delete this->my_data;
    }
}
template <class T>
void Stack<T>::push(const int& other)
{
    if(this->max_size<len){
        return;
    }
    my_data[len]=other;
    ++(this->len);
}
template <class T>
void Stack<T>::out_data()
{
    if(len<=0){
        return;
    }
    --(this->len);
}
template <class T>
T Stack<T>::get_data()
{
    return this->my_data[len-1];
}
template <class T>
bool Stack<T>::is_empty()
{
    if(this->len==0){
        return true;
    }
    return false;
}

main.cpp文件:

#include <iostream>
#include "stack.hpp"
using namespace std;
int main()
{
    Stack<int> s(12);
    s.push(1);
    s.push(2);
    s.push(3);
    while(!s.is_empty()){
        cout<<s.get_data()<<endl;
        s.out_data();
    }
    return 0;
}

結(jié)果圖:

分析:因?yàn)檫@次我們把函數(shù)的實(shí)現(xiàn)放在了hpp文件里面,當(dāng)我們調(diào)用頭文件的時(shí)候問編譯一次,還有就是當(dāng)調(diào)用聲明的時(shí)候也會編譯一次,所以就達(dá)到了類模板的使用要求,所以這次我們就可以鏈接到。

5.3類模板的特化

#include <iostream>
using namespace std;
template<class T1>
class A
{
public:
    A()
    {
        cout<<"A的基礎(chǔ)模板"<<endl;
    }
};
template <>
class A <int>
{
public:
    A()
    {
        cout<<"A的特化模板"<<endl;
    }
};
template <class T2,class T3>
class B
{
public:
  B()
  {
      cout<<"B的基礎(chǔ)模板"<<endl;
  }
};
template <class T2>
class B<T2,float>
{
public:
    B()
    {
        cout<<"B的偏化模板"<<endl;
    }
};
int main()
{
  A<float> a;
  A<int> a1;
  B<int ,int> b1;
  B<int ,float> b2;
    return 0;
}

結(jié)果圖:

分析:當(dāng)使用類模板去定義對象時(shí),因?yàn)榫唧w指定使參數(shù)類型,所以他將優(yōu)先調(diào)用與之指定類型相匹配的特化或偏特化版本。否則,將直接調(diào)用全特化。

5.4C++中類模板中的內(nèi)嵌類

內(nèi)嵌類一般情況下是為外圍類而服務(wù):比如說:STL容器中所提供的迭代器就是一種內(nèi)嵌類。內(nèi)嵌類并不是對外公開的,只做為外圍類的一個(gè)輔助類。隱藏在外圍類的內(nèi)部,對外不可以見。只能通過::域名訪問的形式,才能訪問到。

代碼實(shí)例:

#include <iostream>
using namespace std;
template <typename  T>
class A
{
public:
    class B
    {
        int a = 100;
        int b = 200;
        static B* c;
    };
};
template <class T>
typename A<T>::B* A<T>::B::c =  nullptr;
int main()
{
    A<int> a;
    cout << sizeof (a) << endl;
    A<float>::B b1;
    cout << sizeof(b1) <<endl;
    return 0;
}

內(nèi)嵌類需要注意的幾點(diǎn)內(nèi)容:

1.內(nèi)嵌類可以訪問定義在外圍類(enclosing class)中的靜態(tài)實(shí)例變量。外圍類不可以訪問嵌套類的成員.

2.不能從內(nèi)嵌類中訪問外部類的非靜態(tài)成員.

3.可以在外部通過作用域限定符調(diào)用.

到此這篇關(guān)于C++函數(shù)模板與類模板相同與不同介紹的文章就介紹到這了,更多相關(guān)C++函數(shù)模板與類模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言代碼鏈表實(shí)現(xiàn)貪吃蛇游戲

    C語言代碼鏈表實(shí)現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了C語言鏈表實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • 詳解C++編程中類的聲明和對象成員的引用

    詳解C++編程中類的聲明和對象成員的引用

    這篇文章主要介紹了詳解C++編程中類的聲明和對象成員的引用,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • 基于C語言實(shí)現(xiàn)泛型編程詳解

    基于C語言實(shí)現(xiàn)泛型編程詳解

    對于C而言,想實(shí)現(xiàn)泛型編程并非易事,甚至可以說非常繁瑣,一大堆坑。最主要也沒有現(xiàn)成的輪子可用。本文就來詳細(xì)為大家講講C語言如何實(shí)現(xiàn)泛型編程詳解,需要的可以參考一下
    2022-07-07
  • 詳解C語言基礎(chǔ)的類型轉(zhuǎn)換

    詳解C語言基礎(chǔ)的類型轉(zhuǎn)換

    這篇文章主要為大家介紹了C語言基礎(chǔ)的類型轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • C++中的拷貝構(gòu)造函數(shù)詳解

    C++中的拷貝構(gòu)造函數(shù)詳解

    大家好,本篇文章主要講的是C++中的拷貝構(gòu)造函數(shù)詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • 一篇文章帶你了解C語言內(nèi)存對齊公式

    一篇文章帶你了解C語言內(nèi)存對齊公式

    這篇文章主要介紹了C語言內(nèi)存對齊,包括內(nèi)存對其的基本概念及用法,以及注意事項(xiàng),并以實(shí)例形式加以說明,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • 用純C語言實(shí)現(xiàn)貪吃蛇游戲

    用純C語言實(shí)現(xiàn)貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了用純C語言實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 深入理解Java事務(wù)的原理與應(yīng)用

    深入理解Java事務(wù)的原理與應(yīng)用

    下面小編就為大家?guī)硪黄钊肜斫釰ava事務(wù)的原理與應(yīng)用。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • C語言實(shí)現(xiàn)繪制LoveBeat愛心曲線的示例代碼

    C語言實(shí)現(xiàn)繪制LoveBeat愛心曲線的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何溧陽C語言實(shí)現(xiàn)繪制LoveBeat愛心曲線,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • C++寫Linux框架示例解析

    C++寫Linux框架示例解析

    這篇文章主要為大家介紹了C++實(shí)現(xiàn)Linux框架示例代碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評論

秭归县| 中阳县| 游戏| 唐海县| 偃师市| 当涂县| 上饶市| 内江市| 汕头市| 锡林郭勒盟| 攀枝花市| 丹凤县| 沙田区| 新安县| 阳泉市| 长武县| 崇阳县| 辽阳市| 六枝特区| 利川市| 左云县| 白城市| 拉萨市| 吉安县| 呼和浩特市| 株洲市| 隆德县| 高邮市| 永顺县| 鞍山市| 东兰县| 罗江县| 理塘县| 青神县| 波密县| 施甸县| 正蓝旗| 泊头市| 郑州市| 文安县| 固始县|