3、explicit修饰的构造函数不能担任转换函数。在很多情况下,隐式转换是有意的,并且是正当的。但有时我们不希望进行这种自动的转换。
例如:为了避免这样的隐式转换,应该象下面这样显式声明该带单一参数的构造函数:
class String {
int size;
char *p;
//..
public:
// 不要隐式转换
explicit String (int sz);
String (const char *s, int size n = 0); // 隐式转换
};
void f ()
{
String s(10);
s = 100; // 现在编译时出错;需要显式转换:
s = String(100); // 好;显式转换
s = "st"; // 好;此时允许隐式转换
}
4、仿函数
仿函数,又或叫做函数对象,是STL六大组件之一;仿函数虽然小,但却极大的拓展了算法的功能,几乎所有的算法都有仿函数版本。例如,查找算法find_if就是对find算法的扩展,标准的查找是两个元素相等就找到了,但是什么是相等在不同情况下却需要不同的定义,如地址相等,地址和邮编都相等,虽然这些相等的定义在变,但算法本身却不需要改变,这都多亏了仿函数。仿函数(functor)又称之为函数对象(function object),其实就是重载了()操作符的struct,没有什么特别的地方。
如以下代码定义了一个二元判断式functor:
struct IntLess
{
bool operator()(int left, int right) const
{
return (left < right);
};
};
为什么要使用仿函数呢?
1).仿函数比一般的函数灵活。
2).仿函数有类型识别,可以作为模板参数。
3).执行速度上仿函数比函数和指针要更快的。
17、string 与 数字之间的转换,转换的方法有很多种,一般使用stringstream来实现转换。比如:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
int i=0;
string temp;
stringstream s;
//string转换为数字
temp = “1234”;
s<<temp;
s>>i;
cout<<i<<endl;
//数字转换为string
i=256;
s<<i;
temp = s.str();
cout<<temp<<end;
system("pause");
return 0;
}
20、stl之map erase方法的正确使用
STL的map表里有一个erase方法用来从一个map中删除掉指令的一个节点,不存在任何问题。
如果删除多一个节点时,需要使用正确的调用方法。比如下面的方法是有问题:
for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter);
}
这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。
正确的使用方法:
1).使用删除之前的迭代器定位下一个元素。STL建议的使用方式
for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter++);
}
或者
for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
ITER iterTmp = iter;
iter++;
cout<<iterTmp->first<<":"<<iterTmp->second<<endl;
mapTest.erase(iterTmp);
}
2). erase() 成员函数返回下一个元素的迭代器
for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
iter=mapTest.erase(iter);
}