zoukankan      html  css  js  c++  java
  • 类模板

    声明:本节内容摘自鸡啄米教程十六  原文链接:http://www.jizhuomi.com/software/55.html

    代码复用是面向对象设计中的重要的软件开发思想,对于软件开发效率很是关键。怎样做好代码复用呢?越是通用的代码越好复用,将类型作为参数,这种程序设计类型就是参数化程序设计。模板就是C++进行参数化设计的工具。利用模板我们可以使用同一段程序处理不同类型的对象。

           什么是类模板呢?类模板就是为类声明一种模板,使得类中的某些数据成员,或某些成员函数的参数,又或者是某些成员函数的返回值可以取任意的数据类型,包括基本数据类型和自定义数据类型。

           类模板的声明形式如下:

           template  <模板参数表>
           类声明

           我们看到,在类的声明之前要加上一个模板参数表,模板参数表里的类型名用来说明成员数据和成员函数的类型,等会可以看下面的例子。

           模板参数表中可以以下两种模板参数:

           1.class  标识符(指明可以接受一个类型参数,就是说这是个不固定的类型,用它生成类时才会产生真正的类型)

           2.类型说明符  标识符(指明可以接受一个由“类型说明符”所指定类型的常量作为参数)

           模板参数表可以包含一个或多个以上两种参数,多于一个时各个参数之间用逗号分隔。鸡啄米提醒大家注意的是,类模板的成员函数必须是函数模板。实际上,类模板并不是有实际意义的代码,它只是一些具有相似功能的类的抽象,就是把这些类的共有部分写成模板,类型作为参数,只有用类模板生成类时才会根据需要生成实际的类的代码。

           用类模板建立对象时的声明形式为:

           模板<模板参数表>  对象名1,...,对象名n;

           此处的模板参数表是用逗号分隔开的若干类型标识符或常量表达式构成。它与上面类模板声明时“模板参数表”中的参数是一一对应的。类型标识符与类模板中的“class  标识符”对应,常量表达式与“类型说明符  标识符”对应。这样声明对象之后系统会根据指定的参数类型和常量值生成一个类,然后建立该类的对象。

    类是对对象的抽象,类模板是对类的抽象。

    一个简单明了的例子:

    // Day731_Test2.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    using namespace std;
    
    struct Student
    {
        int id;//学号
        double average;//平均分
    };
    //类模板,用来对任意类型的数据进行存取
    template <class T>
    class Store
    {
    public:
        Store(void);//默认形式(无参数)构造函数
        T GetElem(void);//获取数据;
        void PutElem(T x);//存入数据
    private:
        T item;//item用来存放任意类型数据
        int haveValue;//标识item是否被存入数据
    };
    //以下是成员函数的实现,注意,类模板的成员函数都是函数模板
    //构造函数的实现
    template <class T>
    Store<T>::Store(void) :haveValue(0){}
    
    //获取数据的函数的实现
    template<class T>
    T Store<T>::GetElem(void)//第一个T表示返回值类型
    {
        //若item没有存入数据,则程序终止
        if (haveValue == 0)
        {
            cout << "item没有存入数据!" << endl;
            exit(1);
        }
        return item;
    }
    
    //存入数据的函数的实现
    template<class T>
    void Store<T>::PutElem(T x)
    {
        haveValue = 1;//将其置为1,表示item已经存入数据
        item = x;//将x的值存入item
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        //声明Student 结构体类型变量,并初始化
        Student g = { 103, 93 };
        //声明两个Store类的对象,数据成员item为int类型
        Store<int>S1, S2;
        //声明Store类对象S3,数据成员item为结构体类型
        Store<Student>S3;
    
        S1.PutElem(7);//向对象S1中存入数值7
        S2.PutElem(-1);//向对象S2中存入数值-1
        //输出S1和S2的数据成员的值
        cout << S1.GetElem()<< " " << S2.GetElem() << endl;
    
        S3.PutElem(g);//向对象S3中存入Student结构体类型变量g
        cout << "The student's id is " << S3.GetElem().id << endl;
        cout << "The student;s average is " << S3.GetElem().average << endl;
    
        return 0;
    }
  • 相关阅读:
    Delphi XE5 for Android (六)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    如何设计并使用FireMonkeyStyle
    Indy发送邮件被kbas退掉
    Indy10收发Hotmail邮件
    一个简单的打印监控示例
    DataSnap侦听端口动态设置问题
    面试题总结一
    spring boot RESTFul API拦截 以及Filter和interceptor 、Aspect区别
  • 原文地址:https://www.cnblogs.com/hnzsb-vv1130/p/7263945.html
Copyright © 2011-2022 走看看