C++泛型编程学习(三)——类模板

本文通过实现一个数组模板类,展示了如何管理不同类型的元素,包括int、char和自定义的Teacher类。深入探讨了类模板的声明与定义,并解决了深拷贝与浅拷贝的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

C++泛型编程学习(二)——类模板中已经介绍了如何在一个文件中,把类模板的方法和实现分开,这里主要记录下类模板的声明和定义分别写在头文件中的方法。

类模板实例

功能:实现一个数组模板类,完成对int、char、Teacher类型元素的管理。这时候如何在Teacher类中有指针类型,就会出现深拷贝和浅拷贝的问题。
- main.cpp

#include <iostream>
#include "MyVector.cpp"    // 模板类必须包含成".cpp",一直出现错误,可能和是在code block中编译有关
#include <string.h>

using namespace std;

class Teacher
{
public:
    friend ostream & operator<<(ostream& out, Teacher &t);
    Teacher& operator=(const Teacher& obj)
    {
        if(m_p != NULL)
        {
            delete[] m_p;
            m_p = NULL;
            age = 33;
        }
        m_p = new char[strlen(obj.m_p)+1];
        strcpy(m_p, obj.m_p);
        age = obj.age;

        return *this;
    }
public:
    Teacher()
    {
        age = 33;

        m_p = new char[1];

        strcpy(m_p, "");
    }

    // 在构造函数中,对Teacher的指针变量分配内存
    Teacher(char* name, int age)
    {
        this->age = age;
//        strcpy(this->name, name);
        m_p = new char[strlen(name)];
        strcpy(m_p, name);
    }

    Teacher(const Teacher& obj)
    {
        m_p = new char[strlen(obj.m_p)+1];
        strcpy(m_p, obj.m_p);
        age = obj.age;
    }

    ~Teacher()
    {
        if(m_p != NULL)
        {
            delete[] m_p;  // 
            m_p = NULL;
        }
    }


    void printT()
    {
        cout << "name:" << m_p << " " << "age:" << age << endl;
//        cout << "name:" << name << endl;
//        cout << "age:" << age << endl;
    }
protected:
private:
    int age;
//    char name[32];
    char* m_p;
};

ostream & operator<<(ostream& out, Teacher &t)
{
    out << t.m_p << " " << "age=" << t.age << endl;

    return out;
}

int main()
{
    Teacher t1("t1", 31), t2("t2", 32), t3("t3", 33), t4("t4", 34);
    myVector<Teacher*> tArray(4);

    tArray[0]  = &t1;
    tArray[1]  = &t2;
    tArray[2]  = &t3;
    tArray[3]  = &t4;

    for(int i=0; i<4; i++)
    {
        Teacher *tmp = tArray[i];
        tmp->printT();
    }

    return 0;
}
  • MyVector.h
#ifndef MYVECTOR_H
#define MYVECTOR_H

#include <iostream>

using namespace std;

template <typename T>
class myVector
{
//    friend ostream& operator<< <T>(ostream &out, const myVector &obj);
public:
    myVector(int size=0);
    myVector(const myVector &obj);  // 拷贝构造函数
    virtual ~myVector();    // 析构函数

    T& operator[](int index);
    myVector &operator=(myVector &obj);
    int getLen()
    {
        return m_len;
    }
protected:
    int m_len;
    T *m_space;
private:

};

#endif // MYVECTOR_H
  • MyVector.cpp
#include "MyVector.h"

#include <iostream>

using namespace std;

//在本编译器中使用友元失败
//template <typename T>
//ostream & operator<<(ostream &out, const myVector<T> &obj)
//{
//    for(int i=0; i<obj.m_len; i++)
//    {
//        out << obj.m_space[i] << " ";
//    }
//    return out;
//}

template <typename T>
myVector<T>::myVector(int size)
{
    m_space = new T[size];
    m_len = size;
}

template <typename T>
myVector<T>::~myVector()
{
    if(m_space != NULL)
    {
        delete [] m_space;
        m_space = NULL;
        m_len = 0;
    }
}

template <typename T>
myVector<T>::myVector(const myVector &obj)
{
    // 根据myV1的大小分配内存
    m_len = obj.m_len;
    m_space = new T[m_len];
    for(int i=0; i<obj.m_len; i++)
    {
        m_space[i] = obj.m_space[i];
    }
}

template <typename T>
T& myVector<T>::operator[](int index)
{
    return m_space[index];
}

// a3 = a2 = a1
template <typename T>
myVector<T> & myVector<T>::operator=(myVector<T> &obj)
{
    // 先把a2的旧的内存释放掉
    if(m_space != NULL)
    {
        delete [] m_space;
        m_space = NULL;
        m_len = 0;
    }

    // 根据a1分配内存,拷贝数据
    m_len = obj.m_len;
    m_space = new T[m_len];
    for(int i=0; i<obj.m_len; i++)
    {
        m_space[i] = obj.m_space[i];
    }

    return *this;   // a2=a1
}

类模板小结

  1. 模板是C++类型参数化的多态工具。C++提供函数模板和类模板
  2. 模板定义以模板说明开始。类属参数必须在模板定义中至少出现一次。
  3. 同一个类属参数可以用于多个模板。
  4. 类属参数可以用于函数的参数类型、返回类型和声明函数中的变量。
  5. 模板由编译器根据实际数据类型实例化,生成可执行代码。实例化的函数模板称为模板函数;实例化的类模板称为模板类
  6. 函数模板可以用多种方式重载。
  7. 类模板可以在类层次中使用。

总结

实践才能理解的更深刻,这里大概有个运行的程序感觉就够了。
附上《传智播客扫地僧c++基础和进阶课堂讲义.docx》下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值