函数模板和类模板的区别

转自:http://blog.csdn.net/csw_100/article/details/5844615

函数模板与类模板有什么区别?
答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定,即函数模板允许隐式调用和显式调用而类模板只能显示调用

这期间有涉及到函数模板与模板函数,类模板与模板类的概念 (类似于类与类对象的区别)

请看下面例子:
注意:模板类的函数声明和实现必须都在头文件中完成,不能像普通类那样声明在.h文件中实现在.cpp文件中,原因可以看链接http://blog.csdn.net/wangzengdi/article/details/28625627

当你不使用这个模版函数或模版类,编译器并不实例化它 ,当你使用时,编译器需要实例化它, 因为编译器是一次只能处理一个编译单元, 也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义 . 所以都放在头文件中 这不同于普通的函数, 在使用普通的函数时,编译时只需看到该函数的声明即可编译, 而在链接时由链接器来确定该函数的其实模板实现不能放在cpp文件中,主要就是CPP在c++编译期间不能决定模板参数的类型,所以不能生成模板函数的实例,所以他会把模板类型带到链接期间,如果这个期间有函数调用了该实例,这个时候由于没有把模板实例到特定类型,就会导致编译错误。

# include "stdafx.h"
# include < iostream >
using namespace std ;

//使用模板创建一个返回最大值的函数
//这是一个函数模板
template < class Type>
Type MaxValue( Type a, Type b)
{
    if ( a > b)
    {
        return a;
    }
    else
        return b;
}

//创建一个堆栈模板类
//这是一个类模板
template < class T>
class Stack
{
public :
    Stack ( ) { m_nPos = 0; }
    ~ Stack ( ) { }

    void Push( T value) ;
    T Pop( ) ;

    bool IsEmpty( )
    {
        return m_nPos = = 0;
    }
    bool HasElement( )
    {
        return ! IsEmpty( ) ;
    }
    bool IsFull( )
    {
        return m_nPos = = STATCK_SIZE;
    }

private :
    int m_nPos;
    //使用常量表示堆栈的大小

    const static int STATCK_SIZE = 100;
    T m_Data[ STATCK_SIZE] ;
} ;
//模板类的成员函数实现

template < class T>
void Stack < T> : : Push( T value)
{
    //使用后置递增操作符

    m_Data[ m_nPos+ + ] = value;
}
template < class T>
T Stack < T> : : Pop( )
{
    //使用前置递减操作符

    return m_Data[ - - m_nPos] ;
}

void TestMaxValue( )
{
    //1.隐式调用
    // 函数模板的实例化在程序调用时自动完成
   cout < < MaxValue( 100 , 204) < < endl ; //MaxValue( 100 , 204) 这是一个模板函数
    cout < < MaxValue( 2. 5002, 30. 003) < < endl ; //MaxValue( 2. 5002, 30. 003)这也是一个模板函数
    // 当然由程序员自己指定也可以
    
    //2.显示调用
    cout < < MaxValue< int > ( 10, 20) < < endl ;
    cout < < MaxValue< double > ( 2. 5002, 30. 003) < < endl ;
}

void TestStack( )
{
    //1.测试模板类(整数)
    Stack < int > intStack; //类模板的实例化由程序员显示的指定
    intStack. Push( 10) ;
    intStack. Push( 20) ;
    intStack. Push( 30) ;

    while ( intStack. HasElement( ) )
    {
        cout < < intStack. Pop( ) < < endl ;
    }

    //2.测试模板类(浮点)
    Stack < float > floatStack; //类模板的实例化由程序员显示的指定
    floatStack. Push( 1. 001) ;
    floatStack. Push( 2. 002) ;
    floatStack. Push( 3. 003) ;

    while ( floatStack. HasElement( ) )
    {
        cout < < floatStack. Pop( ) < < endl ;
    }

    //3.测试动态创建对象
    //Stack创建的指针必须指明类型

    Stack < int > * pInt = new Stack < int > ( ) ; 类模板的实例化由程序员显示的指定
    pInt- > Push( 10);
    pInt- > Push( 20) ;
    pInt- > Push( 30) ;

    while ( pInt- > HasElement( ) )
    {
        cout < < pInt- > Pop( ) < < endl ;
    }
    if ( pInt ! = NULL )
    {
        delete pInt;
        pInt = NULL ;
    }
} 

你可能感兴趣的:(c-c++,函数模板,类模板,模板类,模板函数,类模板实例化)