C++STL中总结I

#首先谈一下STL的头文件

序号

功能

头文件

备注

1

迭代器

#include<iterator>

2

I/O流

#include<iostream>

#include<fstream>

#include<sstream>

分别是标准I/O

文件I/O

字符串I/O

3

字符串

#include<string>

string类

4

函数对象

#include<functional>

5

容器

#include<vector>

#include<deque>

#include<list>

#include<queue>

#include<stack>

#include<set>

#include<map>

向量容器

双端队列容器

链表容器

队列/优先队列

集合/多重集合

映射/多映射

6

算法

#include<algorithm>

7

数值算法

#include<numeric>

#浅谈命名空间namespace

在C++中,命名空间用于指定函数范围,以防止名称冲突。在开发大规模软件时尤其要注意,不同厂家开发的类库或函数库中可能存在多个相同的函数名或类名,那么调用时究竟对用哪一个呢?这时就需要用到命名空间这个概念了,它可以作为附加信息来区分不同库中相同名称的函数、类、变量等。本质上,命名空间就是定义了一个范围,指出了名称的上下文。下面的代码说明了命名空间的作用:

#include<iostream>
using namespace std;
namespace myfun{
    void fun()
    {cout<<"这是myfun中的fun"<<endl;}
};
namespace yourfun{
    void fun()
    {cout<<"这是yourfun中的fun"<<endl;}
};

using namespace myfun;//主要用myfun
int main()
{
    fun();//myfun::fun()
    yourfun::fun();//临时使用yourfun
    return 0;
}

由程序输出可见,使用using namespace 指令可以告知编译器接下来的代码默认使用哪个命名空间中的名称。上面的代码using namespace myfun表示后续的名称默认来自命名空间myfun,在调用myfun命名空间中的fun函数时可以不加前缀。当然,若要调用另一个命名空间yourfun中的fun函数,则需要加上前缀才能调用yourfun::fun()

#泛型编程

泛型编程(Generic Programming)就是采用一种“通用”的类型来进行代码的编写,使程序独立于特定的数据类型。泛型编程的目的在于实现更快捷的代码重用,使程序设计者将编程的主要精力集中在程序逻辑上,规避由于不同的数据类型给程序编写带来的麻烦。例如

T Max(T a,T b)
{
    return (a>b)?a:b;
}

注意:此处的T只是一个类型占位符,代表一个参数化的数据类型,也就是所说的“泛型”。在调用该Max函数时,可根据需要对T进行实例化,使Max函数可以同时处理上述各种不同的数据类型,例如

#include<iostream>
using namespace std;
template<class T>
T Max(T a,T b)
{
    if(a>b)
        return a;
    return b;
}
int main()
{
    int a=5,b=3;
    float x=1.3,y=2.8;
    char m='A',n='B';
    cout<<Max(a,b)<<endl;//完整写法 Max<int>(a,b)
    cout<<Max(x,y)<<endl;//完整写法 Max<float>(a,b)
    cout<<Max(m,n)<<endl;//完整写法 Max<char>(a,b)
    return 0;
}

简单解释一下,定义了函数模板Max,其参数类型为T,函数模板的功能是返回两个参数a和b中较大的值。在主函数中调用Max函数,编译器依据实参的类型来推导类型参数T的实际取值,完成函数模板的“具现”并返回比较结果后输出。例如,Max模板的调用的完整写法是Max<int>(a,b),其中Max<int>部分用于完成函数模板的具现,告知编译器Max模板的类型参数为int,紧接着的(a,b)用于向函数传递实参。

注意,在命名空间std下已经有系统预定义的max函数,如果不小心写的时候写的是max,可能会出现类似"Error] call of overloaded 'max(int &, int&)' is ambiguous"的错误提示。解决的方法之一是改成Max,二是在max(a,b)前面加上::将其变成::max(a,b),这样就表示调用此处定义的max,而不是系统std命名空间下的std::max函数。

此处给一个交换两个数的数值的模板

template<class T1,class T2>
void swap(T1& a,T2& b)
{
    T1 t;
    t=a;
    a=(T2)b;
    b=(T1)t;
}

#函数的重载

函数名相同但函数参数的类型不同或者参数的个数不同,这样的一组函数称为重载函数。C++的函数重载机制是面向对象程序设计的重要特性,不需要为功能相似、参数不同的函数选用不同的函数名,增强了程序的可读性,以下是函数模板的重载方法

#include<iostream>
using namespace std;
template<class T1>
int sum(T1 a,T1 b)
{
    return a+b;
}
template<class T1>
int sum(T1 a,T1 b,T1 c)
{
    return a+b+c;
}
int main()
{
    int a=1,b=2,c=3;
    cout<<sum(a,b)<<endl;
    cout<<sum(a,b,c)<<endl;
    return 0;
}

#类模板

简单来说,“类模板”是用于生成具体类的一个“模子”,但相对于函数模板而言,类模板的类型参数涉及的内容更多。类中的成员变量的类型、成员函数参数的类型以及成员函数返回值的类型等都需要进行参数化,才能适应多种数据类型。

template<class T>  //类型参数T,与模板函数一样
class 类名    //类的定义
{
    .....    //内容
};           //不要忘记;

语法规则

①全局类型与模板类型同名:依据“局部优先”原则决定数据类型

②类型参数带缺省类型

template<class T1=char, class T2 = int>
class A
{
    T1 m1;
    T2 m2;
    .....
};

A<> a:按照缺省值进行实例化

A<double> a:T1是double,T2是int

A<int, bool> a:按照int,bool进行设置

③类模板组合

template<class U>
class A
{
    A<U> *p;//在类模板定义的内部引用自身,引用本类时可以省略<U>,直接写成A*p也可以
};
template<class U>
class B
{
    A<U>&a,*b;//在类模板的定义中内嵌其他模板类的对象,引用其他模板时,<U>不可省略
};

#模板特化

模板特化是指对于某些特殊的数据类型,不能用模板的通用实例化方法或程序逻辑来处理时,对这种特殊的数据类型需要进行单独设计和定义。

template<class T>
bool IsEqual(T t1,T t2)
{
    if(t1==t2)
        return true;
    return false;
}
template<>  //函数模板特化
bool IsEqual(char *t1,char *t2)
{
    if(strcmp(t1,t2)==0)
        return true;
    return false;
}
int main()
{
    char s1[]="ABC";
    char s2[]="ABD";
    cout<<IsEqual(15,15)<<endl;
    cout<<IsEqual(s1,s2)<<endl;
    return 0;
}

template<>叫做“完全特化”的类模板,之所以叫“完全特化”,是因为在这个类模板的定义中,template后的<>中没有任何的类型参数,也就意味着类模板中用到的所有参数类型必须在定义的时候加以给定。而

template<class T>
class vector<bool,T>

这种情况叫做“部分特化”,是指在有多个类型参数的模板定义中,“特化”其部分的类型参数,保留其余的类型参数

三种特化的原则为

特化模板>>部分特化模板>>普通函数

#操作符重载(以chainNode为例,主要是<<重载)

template<class T>
void chain<T>::output(ostream& out) const
{// Put the list into the stream out.
   for (chainNode<T>* currentNode = firstNode;
                      currentNode != NULL;
                      currentNode = currentNode->next)
      out << currentNode->element << "  ";
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const chain<T>& x)
   {x.output(out); return out;}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值