STL学习总结
STL就是Standard Template Library,标准模板库。这可能是一个历史上最令人兴奋的工具的最无聊的术语。从根本上说,STL是一些“容器”的集合。这些“容器”有list, vector,set,map等。STL也是算法和其它一些组件的集合。
这里的“容器”和算法的集合指的是世界上非常多聪明人非常多年的杰作。
是C++标准库的一个重要组成部分,它由Stepanov and Lee等人最先开发。它是与C++差点儿同一时候開始开发的;一開始STL选择了Ada作为实现语言,但Ada有点不争气。最后他们选择了C++,C++中已经有了模板。STL又被增加进了C++库。
1996年,惠普公司又免费公开了STL,为STL的推广做了非常大的贡献。
STL提供了类型安全、高效而易用特性的STL无疑是最值得C++程序猿骄傲的部分。
每个C++程序猿都应该好好学习STL。大体上包含container(容器)、algorithm(算法)和iterator(迭代器),容器和算法通过迭代器能够进行无缝连接。
一、基础知识
1、泛型技术
泛型技术的实现方法有多种。比方模板。多态等。模板是编译时决定,多态是执行时决定,其它的比方RTTI也是执行时确定。
多态是依靠虚表在执行时查表实现的。比方一个类拥有虚方法。那么这个类的实例的内存起始地址就是虚表地址。能够把内存起始地址强制转换成int*,取得虚表。然后(int*)*(int*)取得虚表里的第一个函数的内存地址,然后强制转换成函数类型,就可以调用来验证虚表机制。
泛型编程(generic programming。以下直接以GP称呼)是一种全新的程序设计思想,和OO。OB,PO这些为人所熟知的程序设计想法不同的是GP抽象度更高,基于GP设计的组件之间偶合度底。没有继承关系,所以其组件间的互交性和扩展性都非常高。我们都知道。不论什么算法都是作用在一种特定的数据结构上的,最简单的样例就是高速排序算法最根本的实现条件就是所排序的对象是存贮在数组里面,由于高速排序就是由于要用到数组的随机存储特性,即能够在单位时间内交换远距离的对象,而不仅仅是相临的两个对象,而假设用联表去存储对象,由于在联表中取得对象的时间是线性的即O[n],这样将使高速排序失去其高速的特点。
也就是说,我们在设计一种算法的时候,我们总是先要考虑其应用的数据结构,比方数组查找,联表查找,树查找,图查找其核心都是查找。但由于作用的数据结构不同将有多种不同的表现形式。数据结构和算法之间这样密切的关系一直是我们曾经的认识。泛型设计的根本思想就是想把算法和其作用的数据结构分离。也就是说,我们设计算法的时候并不去考虑我们设计的算法将作用于何种数据结构之上。
泛型设计的理想状态是一个查找算法将能够作用于数组。联表。树,图等各种数据结构之上,变成一个通用的。泛型的算法。
2、四种类型转换操作符
static_cast 将一个值以符合逻辑的方式转换。应用到类的指针上,意思是说它同意子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同一时候,也能够执行相反动作:转换父类为它的子类。
比如:float x;
Count<<static_cast<int>(x);//把x作为整型值输出
dynamic_cast 将多态类型向下转换为事实上际静态类型。仅仅用于对象的指针和引用。当用于多态类型时。它同意随意的隐式类型转换以及相反过程。dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。
检測在执行时进行。
假设被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL.
比如:class Car;
class Cabriolet:public Car{
…
};
class Limousline:public Car{
…
};
void f(Car *cp)
{
Cabriolet *p = dynamic_cast< Cabriolet > cp;
}
reinterpret_cast 转换一个指针为其它类型的指针。它也同意从一个指针转换为整数类型。反之亦然。这个操作符能够在非相关的类型之间转换。
操作结果仅仅是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做不论什么类型的检查和转换。
比如:
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B *>(a);
const_cast一般用于强制消除对象的常量性。
比如:
class C {};
const C *a = new C;
C *b = const_cast<C *>(a);
其它三种操作符是不能改动一个对象的常量性的。
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、命名空间namespace
解决在使用不同模块和程序库时,出现名称冲突问题。
5、C++标准程序库中的通用工具。
由类和函数构成。这些工具包含:
数种通用类型
一些重要的C函数
数值极值
二、STL六大组件
容器(Container)
算法(Algorithm)
迭代器(Iterator)
仿函数(Function object)
适配器(Adaptor)
空间配置器(allocator)
1、容器
作为STL的最主要组成部分--容器,分为向量(vector)。双端队列(deque),表(list),队列(queue),堆栈(stack),集合(set),多重集合(multiset)。映射(map),多重映射(multimap)。
容器 |
特性 |
所在头文件 |
向量vector |
能够用常数时间訪问和改动随意元素。在序列尾部进行插入和删除时。具有常数时间复杂度,对随意项的插入和删除就有的时间复杂度与到末尾的距离成正比,尤其对向量头的增加和删除的代价是惊人的高的 |
<vector> |
双端队列deque |
基本上与向量同样,唯一的不同是,其在序列头部插入和删除操作也具有常量时间复杂度 |
<deque> |
表list |
对随意元素的訪问与对两端的距离成正比,但对某个位置上插入和删除一个项的花费为常数时间。 |
<list> |
队列queue |
插入仅仅能够在尾部进行。删除、检索和改动仅仅同意从头部进行。依照先进先出的原则。 |
<queue> |
堆栈stack |
堆栈是项的有限序列。并满足序列中被删除、检索和改动的项仅仅能是近期插入序列的项。即依照后进先出的原则 |
<stack> |
集合set |
由节点组成的红黑树。每个节点都包含着一个元素。节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有同样的次序,具有高速查找的功能。可是它是以牺牲插入删除操作的效率为代价的 |
<set> |
多重集合multiset |
和集合基本同样,但能够支持反复元素具有高速查找能力 |
<set> |
映射map |
由{键,值}对组成的集合,以某种作用于键对上的谓词排列。 具有高速查找能力 |
<map> |
多重集合multimap |
比起映射,一个键能够相应多了值。具有高速查找能力 |
<map> |
STL容器能力表:
2、算法
算法部分主要由头文件<algorithm>。<numeric>和<functional>组成。
< algorithm>是全部STL头文件里最大的一个,它是由一大堆模版函数组成的。能够觉得每个函数在非常大程度上都是独立的,当中经常使用到的功能范 围涉及到比較、交换、查找、遍历操作、复制、改动、移除、反转、排序、合并等等。<numeric>体积非常小,仅仅包含几个在序列上面进行简单数学运算的模板函数。包含加法和乘法在序列上的一些操作。
<functional>中则定义了一些模板类,用以声明函数对象。
STL的算法也是非常优秀的,它们大部分都是类属的,基本上都用到了C++的模板来实现,这样,非常多相似的函数就不用自己写了。仅仅要用函数模板就能够了。
我们使用算法的时候,要针对不同的容器,比方:对集合的查找,最好不要用通用函数find()。它对集合使用的时候,性能非常的差。最好用集合自带的find()函数,它针对了集合进行了优化,性能非常的高。
3、迭代器
它的具体实如今<itertator>中,我们全然能够不管迭代器类是怎么实现的,大多数的时候。把它理解为指针是没有问题的(指针是迭代器的一个特例,它也属于迭代器),可是,决不能全然这么做。
迭代器功能 |
||
输入迭代器 Input iterator |
向前读 Reads forward |
istream |
输出迭代器 Output iterator |
向前写 Writes forward |
ostream,inserter |
前向迭代器 Forward iterator |
向前读写 Read and Writes forward |
|
双向迭代器 Bidirectional iterator |
向前向后读写 Read and Writes forward and backward |
list,set,multiset,map,mul timap |
随机迭代器 Random access iterator |
随机读写 Read and Write with random access |
vector,deque,array,string |
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).执行速度上仿函数比函数和指针要更快的。
怎么使用仿函数?
除了在STL里。别的地方你非常少会看到仿函数的身影。而在STL里仿函数最经常使用的就是作为函数的參数,或者模板的參数。
在STL里有自己提前定义的仿函数,比方全部的运算符,=,-。*。、比方'<'号的仿函数是less
template<class _Ty>
struct less : public binary_function<_Ty, _Ty, bool>
{ // functor for operator<
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
从上面的定义能够看出。less从binary_function<...>继承来的,那么binary_function又是什么的?
template<class _Arg1, class _Arg2, class _Result>
struct 、适配器
适配器是用来改动其它组件接口的STL组件,是带有一个參数的类模板(这个參数是操作的值的数据类型)。
STL定义了3种形式的适配器:容器适配器,迭代器适配器,函数适配器。
容器适配器:包含栈(stack)、队列(queue)、优先(priority_queue)。使用容器适配器。stack就能够被实现为基本容器类型(vector,dequeue,list)的适配。能够把stack看作是某种特殊的vctor,deque或者list容器。仅仅是其操作仍然受到stack本身属性的限制。queue和priority_queue与之相似。容器适配器的接口更为简单。仅仅是受限比一般容器要多。
迭代器适配器:改动为某些基本容器定义的迭代器的接口的一种STL组件。
反向迭代器和插入迭代器都属于迭代器适配器,迭代器适配器扩展了迭代器的功能。
函数适配器:通过转换或者改动其它函数对象使其功能得到扩展。这一类适配器有否定器(相当于"非"操作)、绑定器、函数指针适配器。函数对象适配器的作用就是使函数转化为函数对象。或是将多參数的函数对象转化为少參数的函数对象。
比如:
在STL程序里,有的算法须要一个一元函数作參数。就能够用一个适配器把一个二元函数和一个数值。绑在一起作为一个一元函数传给算法。
比如:
find_if(coll.begin(), coll.end(), bind2nd(greater <int>(), 42));
这句话就是找coll中第一个大于42的元素。
greater <int>(),事实上就是">"号,是一个2元函数
bind2nd的两个參数。要求一个是2元函数。一个是数值。结果是一个1元函数。
bind2nd就是个函数适配器。
6、空间配置器
STL的内存配置器在我们的实际应用中差点儿不用涉及。但它却在STL的各种容器背后默默做了大量的工作。STL内存配置器为容器分配并管理内存。统一的内存管理使得STL库的可用性、可移植行、以及效率都有了非常大的提升。
SGI-STL的空间配置器有2种。一种仅仅对c语言的malloc和free进行了简单的封装,而还有一个设计到小块内存的管理等。运用了内存池技术等。在SGI-STL中默认的空间配置器是第二级的配置器。
SGI使用时std::alloc作为默认的配置器。
A).alloc把内存配置和对象构造的操作分开,分别由alloc::allocate()和::construct()负责,同样内存释放和对象析够操作也被分开分别由alloc::deallocate()和::destroy()负责。这样能够保证高效。由于对于内存分配释放和构造析够能够依据具体类型(type traits)进行优化。比方一些类型能够直接使用高效的memset来初始化或者忽略一些析构函数。对于内存分配alloc也提供了2级分配器来应对不同情况的内存分配。
B).第一级配置器直接使用malloc()和free()来分配和释放内存。第二级视情况採用不同的策略:当需求内存超过128bytes的时候。视为足够大,便调用第一级配置器;当需求内存小于等于128bytes的时候便採用比較复杂的memeory pool的方式管理内存。
C).不管allocal被定义为第一级配置器还是第二级。SGI还为它包装一个接口,使得配置的接口能够符合标准即把配置单位从bytes转到了元素的大小:
template<、auto_ptr 不能用new[]所生成的array作为初值,由于释放内存时用的是delete,而不是delete[]
2、就搜寻速度而言,hash table通常比二叉树还要快5~10倍。hash table不是C++标准程序库的一员。
3、迭代器使用过程中优先选用前置式递增操作符(++iter)而不是选择后置式递增操作符(iter++)。
3、迭代器三个辅助函数:advance(),distance(),iter_swap()。
advance()可令迭代器前进
distance()可处理迭代器之间的距离。
iter_swap()可交换两个迭代器所指内容。
4、hasp函数 makeheap()、push_heap()、pop_heap()、sort_heap()
5、’/0’在string之中并不具有特殊意义。可是在一般C形式的string中却用来标记字符串结束。在string中,字符 ‘/0’和其它字符的地位全然同样。string中有三个函数能够将字符串内容转换成字符数组或C形式的string。
data() 以字符数组的形式返回字符串内容。但末未追加’/0’字符,返回类型并非有效的C形式string。
c_str() 以C形式返回字符串内容(在末尾端增加’/0’字符)。
copy() 将字符串内容拷贝到“调用者提供的字符数组”中。不增加’/0’字符。
6、容器中用empty来取代检查size是否为0;当使用new得到指针的容器时,切记在容器销毁前delete那些指针。千万不要把auto_ptr放入容器中。
7、尽量使用vector和string来取代动态申请的数组。避免使用vector<bool>,vector<bool>有两个问题.第一,它不是一个真正STL容器。第二,它并不保存bool类型。
8、迭代器使用过程中。尽量使用iterator取代const_iterator,reverse_iterator和const_reverse_iterator;使用distance和advance把const_iterators转化成iterators。
typedef deque<int> IntDeque; // 和曾经一样
typedef IntDeque::iterator Iter;
typedef IntDeque::const_iterator ConstIter;
IntDeque d;
ConstIter ci;
... // 让ci指向d
Iter i(d.begin()); // 初始化i为d.begin()
advance(i, distance(i, ci)); // 调整i,指向ci位置
9、避免对set和multiset的键值进行改动。
10、永远让比較函数对同样元素返回false。
11、排序选择:
1)假设你须要在vector、string、deque或数组上进行全然排序。你能够使用sort或stable_sort。
2)假设你有一个vector、string、deque或数组,你仅仅须要排序前n个元素,应该用partial_sort。
3)假设你有一个vector、string、deque或数组,你须要鉴别出第n个元素或你须要鉴别出最前的n个元素,而不用知道它们的顺序,nth_element是你应该注意和调用的。
4)假设你须要把标准序列容器的元素或数组分隔为满足和不满足某个标准。你大概就要找partition或stable_partition。
5)假设你的数据是在list中,你能够直接使用partition和stable_partition,你能够使用list的sort来取代sort和stable_sort。
假设你须要partial_sort或nth_element提供的效果,你就必须间接完毕这个任务。
12、假设你真的想删除东西的话就在相似remove的算法后接上erase。remove从一个容器中remove元素不会改变容器中元素的个数,erase是真正删除东西。
13、提防在指针的容器上使用相似remove的算法。在调用相似remove的算法前手动删除和废弃指针。
14、、容器中使用自己定义的结构体时,假设用到拷贝与赋值,结构体须要重载operator=符号;比較容器分成相等与不等。相等时重载operator==符号,不等时重载operator<符号。比方set、map、multiset、multimap、priority_queue等容器类要求重载operator<符号。
16、Map/Multimap,Sets/Multisets都不能用push_back,push_front,由于它是自己主动排序的。
Set内的同样数值的元素仅仅能出现一次。Multisets内可包含多个数值同样的元素。
Map内的同样数值的元素仅仅能出现一次。Multimap内可包含多个数值同样的元素。内部由二叉树实现。便于查找。
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;
}
18、对于自己定义的结构体,放入容器中,最好不要对容器进行内存初始化(不要调用memset,zeromemory函数),否则假设结构体中有指针类型的变量时,就会出现故障。
19、Vector的函数泄漏问题
定义了一个
struct temp
{
char name[256];
int i;
}
Vector<temp> vect;
当对这个vect执行pushback一些temp的结构体后。执行clear这样是否会内存泄露?能够释放掉temp结构体中的name内存吗?
解决方法:
不行,clear仅仅是把那些元素全部删除掉。并非释放内存。
再者,你这种定义容器是不须要释放内存的。假设你这样定义,std::vector <temp> *pVec。就须要了。先pVec->clear()再 pVec->swap( (std::vector <temp>)(*pVec) )。就能实现内存的释放。
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);
}
21、boost::bind总结
bind 是一组重载的函数模板.用来向一个函数(或函数对象)绑定某些參数. bind的返回值是一个函数对象.
性质:
不是函数,是一个class,是一个多元仿函数
模板參数:
带模板參数。但不须要,会自己主动推导!
构造函数參数:
格式:_须要绑定类型,_參数1。_參数2,_參数3,_參数4…
_须要绑定类型:能够是普通函数,类成员函数。成员变量
_參数N:能够是一个占位符,或者实际參数。
假设绑定的类型是一个类成员函数或变量,那么第一个參数必须是对象或者对象指针。
仿函数參数:
随意
仿函数返回值
假设绑定的是函数。返回绑定函数的返回值。
假设绑定是成员变量,返回成员变量值
占位符:
_1,_2,_3,_4….._9
占位符的数字表示仿函数时相应參数的位置。
一个bind里能够嵌入多个bind,但占位符是相对于这一块的bind是共享。
注意事项
a)假设绑定的是类函数,传入对象时,最好使用对象指针,假设使用对象实例会产生多次对象复制。假设非要传对象而不想多次被复制传在在使用ref或cref(ref的const版)
b) 跟lambda混用时一定要特别小心
第一、 会与lambda的占位符有冲突
第二、 lambda库里有跟同样名字的bind,功能相似,但没有此功能强大
总结
无模板參数,构函数对绑定函数负责,仿函数是随意的。
举例说明
例一:
void nine_arguments(
int i1,int i2,int i3,int i4,
int i5,int i6,int i7,int i8, int i9) {
std::cout << i1 << i2 << i3 << i4 << i5
<< i6 << i7 << i8 << i9 << '/n';
}
int main() {
int i1=1,i2=2,i3=3,i4=4,i5=5,i6=6,i7=7,i8=8,i9=9;
(boost::bind(&nine_arguments,_9,_2,_1,_6,_3,_8,_4,_5,_7))
(i1,i2,i3,i4,i5,i6,i7,i8,i9);
}
输出结果921638457
推荐书籍:
《C++标准程序库》本书将焦点放在标准模板库(Standard Template Library)身上,检验当中的容器(containers)、迭代器(iterators)、仿函数(functors)和算法(algorithms)。
你还能够找到特殊容器、字符串(strings)、数值类别、国际化议题、IOStream。每个组件都有深刻的呈现,包含其介绍、设计、运用实例、细部讲解、陷阱、意想不到的危急,以及相关类别和函数的确切标记(signature)和定义。
一份见解深刻的基础概念介绍和一个程序库综合俯视。会对新手带来高速的提升。
《泛型编程与STL》阐述了泛型程序设计的中心观念:concepts,modeling, refinement,并为你展示这些观念怎样导出 STL 的基础概念:iterators, containers, function objects.循此路线,你能够把 STL 想象为一个由 concepts(而非明白之 functions 或 classes)组成的 library.你将学习其正式结构并因此获得其潜在威力之完整优势.
《Effective STL》阐述了怎样有效地使用STL(Standard Template Library, 标准模板库)进行编程。
书中讲述了怎样将STL组件组合在一起,从而利用库的设计。这些内容会帮助你针对简单的问题开发出简单、直接的解决方式,而且针对复杂的问题开发出精致的解决方式。
书中还描写叙述了常见的STL使用错误,并告诉你怎样避免这些错误。
《STL源代码剖析》了解源代码。看到vector的实现、list的实现、heap的实现、deque的实现、RB-tree的实现、hash-table的实现、set/map 的实现;你将看到各种算法(排序、搜寻、排列组合、数据移动与复制…)的实现;你甚至将看究竟层的memory pool 和高阶抽象的traits 机制的实现。
STL China 现场:http://www.stlchina.org/
STL学习总结的更多相关文章
- 标准模板库(STL)学习探究之stack
标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
- ###STL学习--vector
点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...
- ###STL学习--关联容器
点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...
- ###STL学习--迭代器
点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的迭代器. ###stl学习 |--迭代 ...
- ###STL学习--函数对象
点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...
- ###STL学习--适配器
点击查看Evernote原文. #@author: gr #@date: 2014-08-24 #@email: forgerui@gmail.com STL中的适配器. ###stl学习 |--迭代 ...
- STL学习:STL库vector、string、set、map用法
本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...
- Effective STL 学习笔记 39 ~ 41
Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...
随机推荐
- android Gallery滑动不流畅的解决
import android.content.Context; import android.util.AttributeSet; import android.view.KeyEvent; impo ...
- 创建Activity
创建Activity 创建 Activity 分为3个步骤: 1.创建一个扩展子Activity的class 2.创建一个Layout 3.在 AndroidMainfest 中 配置这个Activ ...
- nodejs安装不了和npm安装不了的解决方法
http://caibaojian.com/nodejs-roll-back.html
- Delphi的RTTI还分为对类和对象的判断,以及对普通属性的判断——相比之下,C++的RTTI实在太弱!
堂堂C++沦落到这个地步,也实在是够可怜的.
- Winform - 全屏显示
//全屏显示 this.WindowState = FormWindowState.Maximized;
- sql:oracle, CURSOR
CursorsYou use a cursor to fetch rows returned by a query. You retrieve the rows into the cursor usi ...
- 关于自动刷新CSS
由于最近系统调整大量的css,希望用户在浏览的时候能即时看到css的更改,而不是继续看到的是客户机上的缓存css. 在网络上找了下,发现很多人推荐一个叫cssrefresh的小工具. http://w ...
- MVC控制器里面使用dynamic和ExpandoObject
MVC控制器里面使用dynamic和ExpandoObject 在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计 ...
- android studio之argument for @notnull parameter 'name'
1)进入刚安装的Android Studio目录下的bin目录.找到idea.properties文件,用文本编辑器打开.2)在idea.properties文件末尾添加一行: disable.and ...
- How to decompile class file in Java and Eclipse - Javap command example(转)
Ability to decompile a Java class file is quite helpful for any Java developer who wants to look int ...