其中long 和 int 范围是[-2^31,2^31),即-2147483648~2147483647。而unsigned范围是[0,2^32),即0~4294967295。也就是说,常规的32位整数只能够处理40亿以下的数。long long 与 unsigned long long:[-2^63, 2^63)与[0,2^64)
int&refVal3=10;// error: initializer must be an object inti=42;// legal for const references only constint&r=42;constint&r2=r+i;doubledval=3.14;constint&ri=dval;
intmain(){stringline;// read line at time until end-of-filewhile(getline(cin,line))cout<<line<<endl;return0;}//string支持下标操作stringstr("some string");for(string::size_typeix=0;ix!=str.size();++ix)cout<<str[ix]<<endl;
vector:push_back、pop_back、erase
for(vector<int>::iteratorit=arr.begin();it!=arr.end();){if(*it==8){it=arr.erase(it);}else{++it;}}//注意上面不能写成/*
for(vector<int>::iterator it=arr.begin(); it!=arr.end(); it ++)
{
if(* it == 8)
{
arr.erase(it); //在erase后,it失效,并不是指向vector的下一个元素,it成了一个“野指针”。
}
}
*/
迭代器是一种检查容器内元素并遍历元素的数据类型。
for(vector<string>::const_iteratoriter=text.begin();iter!=text.end();++iter)*iter=" ";// error: *iter is constvector<int>nums(10);// nums is nonconstconstvector<int>::iteratorcit=nums.begin();*cit=1;// ok: cit can change its underlying element++cit;// error: can't change the value of cit
bitset:
bitset<32>bitvec;// 32 bits, all zero// bitvec1 is smaller than the initializerbitset<16>bitvec1(0xffff);// bits 0 ... 15 are set to 1// bitvec2 same size as initializerbitset<32>bitvec2(0xffff);// bits 0 ... 15 are set to 1; 16 ... 31 are 0// on a 32-bit machine, bits 0 to 31 initialized from 0xffffbitset<128>bitvec3(0xffff);// bits 32 through 127 initialized to zero stringstr("1111111000000011001101");bitset<32>bitvec5(str,5,4);// 4 bits starting at str[5], 1100bitset<32>bitvec6(str,str.size()-4);// use last 4 characters
// Disaster: Function returns a reference to a local objectconststring&manip(conststring&s){stringret=s;// transform ret in some wayreturnret;// Wrong: Returning reference to a local object!}
这个函数会在运行时出错,因为它返回了局部对象的引用。当函数执行完毕,字符串 ret 占用的储存空间被释放,函数返回值指向了对于这个程序来说不再有效的内存空间。确保返回引用安全的一个好方法是:请自问,这个引用指向哪个在此之前存在的对象?
面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。在 C++ 中,用类进行数据抽象,用类派生从一个类继承另一个:派生类继承基类的成员。动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数。继承和动态绑定在两个方面简化了我们的程序:能够容易地定义与其他类相似但又不相同的新类,能够更容易地编写忽略这些相似类型之间区别的程序。许多应用程序的特性可以用一些相关但略有不同的概念来描述。例如,书店可以为不同的书提供不同的定价策略,有些书可以只按给定价格出售,另一些书可以根据不同的折扣策略出售。可以给购买某书一定数量的顾客打折,或者,购买一定数量以内可以打折而超过给定限制就付全价。面向对象编程(Object-oriented programming,OOP)与这种应用非常匹配。通过继承可以定义一些类型,以模拟不同种类的书,通过动态绑定可以编写程序,使用这些类型而又忽略与具体类型相关的差异。
在 C++ 中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。用引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实际类型所定义的。除了构造函数之外,任意非 static 成员函数都可以是虚函数。