现在的位置: 首页 > 综合 > 正文

函数模板与类模板的区别及STL中的迭代器

2013年08月28日 ⁄ 综合 ⁄ 共 2996字 ⁄ 字号 评论关闭

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

即函数模板允许隐式调用和显式调用而类模板只能显示调用

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

请看下面例子

注意:模板类的函数声明和实现必须都在头文件中完成,不能像普通类那样声明在.h文件中实现在.cpp文件中,原因可以看链接http://hi.baidu.com/cn_rigel/blog/item/6cf6fc083723e2286a60fb53.html

# 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> 
Stack < T> : : Pop( ) 
{ 
    //使用前置递减操作符

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

    cout < < MaxValue< int > ( 10, 20) < < endl ; 
    cout < < MaxValue< double > ( 2. 5002, 30. 003) < < endl ; 
} 
void TestStack( ) 
{ 
    //测试模板类(整数)
    Stack < int > intStack; //类模板的实例化由程序员显示的指定
    intStack. Push( 10) ; 
    intStack. Push( 20) ; 
    intStack. Push( 30) ; 
    while ( intStack. HasElement( ) ) 
    { 
        cout < < intStack. Pop( ) < < endl ; 
    } 
    //测试模板类(浮点)
    Stack < float > floatStack; //类模板的实例化由程序员显示的指定
    floatStack. Push( 1. 001) ; 
    floatStack. Push( 2. 002) ; 
    floatStack. Push( 3. 003) ; 
    while ( floatStack. HasElement( ) ) 
    { 
        cout < < floatStack. Pop( ) < < endl ; 
    } 
    //测试动态创建对象
    //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 ; 
    } 
}


STL中迭代器的工作原理,迭代器与普通指针有什么区别?
迭代器和指针相同的地方
1、指针和iterator都支持与整数进行+,-运算,而且其含义都是从当前位置向前或者向后移动n个位置
2、指针和iterator都支持减法运算,指针-指针得到的是两个指针之间的距离,迭代器-迭代器得到的是两个迭代器之间的距离
3、通过指针或者iterator都能够修改其指向的元素
通过上面这几点看,两者真的很像,但是两者也有着下面的几个不同地方
1、cout操作符可以直接输出指针的值,但是对迭代器进行在操作的时候会报错。通过看报错信息和头文件知道,迭代器返回的是对象引用而不是对象的值,所以cout只能输出迭代器使用*取值后的值而不能直接输出其自身。
2、指针能指向函数而迭代器不行,迭代器只能指向容器
这就说明了迭代器和指针其实是完全不一样的概念来的。指针是一种特殊的变量,它专门用来存放另一变量的地址,而迭代器只是参考了指针的特性进行设计的一种STL接口。
笔者曾在网上看到这样一种说法:迭代器是广义指针,而指针满足所有迭代器要求。迭代器是STL算法的接口,而指针是迭代器,因此STL算法可以使用指针来对基于指针的非STL容器进行操作。
笔者觉得上面说法也有几分道理,但是到底正不正确就留给看官自己判断了。但是有一点希望大家注意的是:千万不要把指针和迭代器搞混了。也许某些编译器使用指针来实现迭代器以至于有些人会误以为指针和迭代器是一个概念来的。

抱歉!评论已关闭.