模板的超详细的案例讲解(下)

9、类模板成员函数 在类外实现

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

//严格来说;类模板的类型 不是Person 而是Person<T1,T2>
template<class T1,class T2>
class Person{
public:
    T1 name;
    T2 age;
public:
    //类内声明
    Person(T1 name, T2 age);
    void showPerson(void);

};

//类外定义
template<class T1, class T2>
Person<T1,T2>::Person(T1 name, T2 age)
{
    cout<<"有参构造"<<endl;
    this->name = name;
    this->age = age;
}

template<class T1, class T2>
void Person<T1,T2>::showPerson()
{
    cout<<"name = "<<name<<", age = "<<age<<endl;
}


int main(int argc, char *argv[])
{
    Person<string,int> ob1("德玛西亚", 18);
    ob1.showPerson();

    Person<int,int> ob2(100,200);
    ob2.showPerson();
    return 0;
}

运行结果:
在这里插入图片描述

10、类模板头文件 和源文件 分离问题

person.hpp //hpp是包含声明和定义的特殊的头文件

#ifndef PERSON_H
#define PERSON_H
#include <iostream>
#include<string>
using namespace std;

//严格来说;类模板的类型 不是Person 而是Person<T1,T2>
template<class T1,class T2>
class Person{
public:
    T1 name;
    T2 age;
public:
    //类内声明
    Person(T1 name, T2 age);
    void showPerson(void);
};

//类外定义
template<class T1, class T2>
Person<T1,T2>::Person(T1 name, T2 age)
{
    cout<<"有参构造"<<endl;
    this->name = name;
    this->age = age;
}

template<class T1, class T2>
void Person<T1,T2>::showPerson()
{
    cout<<"name = "<<name<<", age = "<<age<<endl;
}

#endif // PERSON_H

main.cpp

#include <iostream>
#include<string>
//include标准是包含头文件 基本上不会包含.cpp
//#include"person.cpp"
#include"person.hpp"
using namespace std;

int main(int argc, char *argv[])
{
    //类模板 会经过两次编译
    //第一次 类模板 本身编译,第二次编译 是类模板的成员调用的时候
    //c++/c 独立文件编译
    //如果 类模板的.cpp和.h分文件 出错的原因 在第二次编译
    //建议.cpp和.h放在一次

    Person<string,int> ob1("德玛西亚", 18);
    ob1.showPerson();
    return 0;
}

运行结果:
在这里插入图片描述

11、类模板 与 友元(了解)

#include <iostream>
#include<string>
using namespace std;
//person类向前声明
template<class T1,class T2> class Person;

//提前声明函数模板 告诉编译器printPerson02函数模板是存在
template<class T1,class T2> void printPerson02(Person<T1,T2> &ob);

template<class T1,class T2>
class Person{
private:
    T1 name;
    T2 age;
public:
    Person(T1 name, T2 age);
    //1、友元函数在类中定义(友元不属于该类成员函数)
    friend void printPerson01(Person<T1,T2> &ob)
    {
        cout<<"name = "<<ob.name<<" ,age = "<<ob.age<<endl;
    }
    //2、友元函数在类外定义 必须告诉编译器 该友元函数是模板函数
    friend void printPerson02<>(Person<T1,T2> &ob);
};
//函数模板
template<class T1,class T2>
void printPerson02(Person<T1,T2> &ob)
{
    cout<<"name = "<<ob.name<<" ,age = "<<ob.age<<endl;
}
template<class T1,class T2>
Person<T1,T2>::Person(T1 name, T2 age)
{
    this->name = name;
    this->age = age;
}
int main(int argc, char *argv[])
{
    Person<string,int> ob("德玛",18);
    //通过友元 访问类模板中的数据
    printPerson01(ob);

    printPerson02(ob);

    return 0;
}

运行结果:
在这里插入图片描述

12、类模板的综合案例

myarray.hpp

#ifndef MYARRAY_HPP
#define MYARRAY_HPP
#include<iostream>
using namespace std;
template<class T>
class MyArray{
private:
    T *addr;
    int capacity;
    int size;
public:
    MyArray(int capacity);
    MyArray(const MyArray &ob);
    ~MyArray();

    //尾插法
    void push_back(const T &val);
    //遍历数组
    void printArray(void);
};

#endif // MYARRAY_HPP

template<class T>
MyArray<T>::MyArray(int capacity)
{
    //对于自定义数据类型 new Person[10]; 数组中的每个元素 都会调用无参构造
    this->addr = new T[capacity];
    this->capacity = capacity;
    this->size = 0;
}

template<class T>
MyArray<T>::MyArray(const MyArray &ob)
{
    this->capacity = ob.capacity;
    this->addr = new T[this->capacity];

    int i=0;
    for(i=0;i<ob.size;i++)
    {
        this->addr[i] = ob.addr[i];
    }

    this->size = ob.size;
}

template<class T>
MyArray<T>::~MyArray()
{
    if(this->addr != NULL)
    {
        delete [] this->addr;
        this->addr =NULL;
    }
}

template<class T>
void MyArray<T>::push_back(const T &val)
{
    // 数组的实际个数size 不能超过 capacity
    if(this->size == this->capacity)
    {
        cout<<"容器已满"<<endl;
        return;
    }
    this->addr[this->size] = val;
    this->size++;
}

template<class T>
void MyArray<T>::printArray()
{
    int i=0;
    for(i=0;i<this->size;i++)
    {
        //如果输出的是自定义数据 Person必须重载<<
        cout<<this->addr[i]<<" ";
    }
    cout<<endl;
}

main.cpp

#include <iostream>
#include<string>
#include"myarray.hpp"
using namespace std;
class Person
{
    friend ostream& operator<<(ostream &out, const Person &ob);
private:
    string name;
    int age;
public:
    Person()
    {
       ;
    }
    Person(string name, int age)
    {
        this->name = name;
        this->age = age;
    }

};
ostream& operator<<(ostream &out, const Person &ob)
{
    out<<"name = "<<ob.name<<", age = "<<ob.age<<endl;
    return out;
}
int main(int argc, char *argv[])
{
    MyArray<char> ob(10);
    ob.push_back('a');
    ob.push_back('b');
    ob.push_back('c');
    ob.push_back('d');

    ob.printArray();

    MyArray<int> ob2(10);
    ob2.push_back(10);
    ob2.push_back(20);
    ob2.push_back(30);
    ob2.push_back(40);
    ob2.printArray();

    //存放自定义 数据
    MyArray<Person> ob3(10);
    ob3.push_back(Person("德玛",18));
    ob3.push_back(Person("风男",19));
    ob3.push_back(Person("小法",20));
    ob3.push_back(Person("瞎子",21));
    ob3.printArray();


    return 0;
}

运行结果:
在这里插入图片描述

发布了52 篇原创文章 · 获赞 42 · 访问量 4922

猜你喜欢

转载自blog.csdn.net/weixin_43288201/article/details/105148734