C++模板

前言

最近在C++知识查漏补缺和巩固的过程中,遇到关于C++模板的问题,查看了C++ Primer这本书,对相关知识进行总结。(第一次尝试MarkDown编写,不知道效果怎么样)

泛型编程

泛型编程最初提出时的动机很简单直接:发明一种语言机制,能够帮助实现一个通用的标准容器库。所谓通用的标准容器库,就是要能够做到,比如用一个List类存放所有可能类型的对象这样的事。比如我们使用vector时,可以是vector、vector,还可以是我们自己定义的数据类型,这就是泛型编程的例子,即我们在编写程序(程序员或者是你编写)的时候,不需要知道具体的数据类型,在“使用的时候”由程序使用者给定相应的类型,为什么“使用的时候”要打引号,因为这样说有一点不严格,因为还有一种方法也能处理在编写程序时不需要知道类型的情况,那就是面向对象编程(OOP),这二者是有区别的:OOP能处理类型在程序运行之前都未知的情况,但泛型编程需要在编译的时候就知道类型,这一要求要早于OPP机制。

C++模板

  • 1模板定义
    使用关键字template,如函数模板定义:
template<typname T>
void Fun(void)
{
    T a;
}
  • 2模板编译
    编译器一个模板定义时,它并不生成代码,因为这个时候编译器并不知道具体类型,只有当使用模板时(这时候程序使用者就会给定相应类型),编译器才会生成代码。这一特殊机制会造成相应的编程影响。
    通常,我们在调用函数时,只需要知道该函数的声明(回想一下,是不是这样的?比如你在写C代码时,如果先写main函数,在其中调用一个函数,而这个函数的定义在main代码之后,则现在我们只需要在main之前声明该被调用的函数,就可以了)。但是我们在使用类对象是,必须已经对该对象进行了定义,同样,我们也不必知道该类对象成员函数的定义,只需要声明(这个声明在哪里呢?就在类的定义里面)。所以,一般我们会把类的定义和普通函数的声明放在.h文件中,而把普通函数和类成员函数的定义放在相应的.cpp文件中。
    但是对于模板程序来说,这一做法不行。普通模板函数的定义、模板类和其成员函数的定义,都需要放在.h文件中,不然编译就会报错。如下程序演示:
    如头文件如下(类定义):
#include <iostream>
        #include <conio.h>
        const int SIZE=8;
        template <class T>
        class Smemory 
        {
            T data[SIZE];
            int count;
        public:
            Smemory(){ count=0; }
            void mput(T x);
            T mget( );
        };

相应源文件(成员函数定义):

#include "ClassTemplateTest.h"
        //定义成员函数mput(),函数的参数类型为T,该函数用于为数据成员 data数组的各个元素赋值
        template <class T>
        void Smemory<T>::mput(T x)
        {
            if(count==8) { cout<<"Memory is full"; return; }
            data[count]=x;
            count++;
        }
        //定义成员函数mget(),函数的返回类型为T,该函数用于取出数据成员 data数组的各个元素
        template <class T>
        T Smemory<T>::mget()
        {
        if(count==0) { cout<<"Memory is empty"; return 0; }
        count--;
        return data[count];
        }

main函数为:

        #include <iostream>
        #include <string.h>
        #include "ClassTemplateTest.h"
        using namespace std;
        void main()
        {
            Smemory<int> mo1;
            int i;
            char ch='A';
            Smemory<char> mo2;
            for(i=0;i<8;i++)
            {
                mo1.mput(i);
                mo2.mput(ch);
                ch++;
            }
            cout<<"Get mo1 => ";
            for(int i=0;i<8;i++)
                cout<<mo1.mget( );
            std::cout<<"\nGet mo2 => ";
            for(i=0;i<8;i++)
                cout<<mo2.mget( );
            _getch();
        }

则报错:
这里写图片描述

而把成员函数放在.h文件就顺利编译通过,可自行验证。

模板实例化

对于类模板,不同的模板类型参数,会实例化不同的类对象,即一个类模板的每个实例都形成一个独立的类。另外,一个类模板的成员函数只有当程序用到它是才进行实例化,如对于上述出现编译错误的情况,如果在main函数中,没有调用mo2.mput()函数,则不会出现该函数的编译错误,即程序在编译过程中并没有生成该函数的实例化代码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值