深入C++ (2)

深入C++ (2)

1.const引用

​ const引用可以用不同类型的对象初始化(只要能从一种类型转换到另一种类型即可),也可以是不可寻址的值,如文字常量.例如:

double a = 9.9;
const int &b = a;
cout << "b = " << b << endl;

​ 最后运行结果会是 b = 9,

​ 当将一个引用初始化为一个const对象的地址时,此时使用非const引用定义是非法的,将导致编译时刻错误,如下面:

const int a = 10;
const int* &p = &a;	//错误

​ 上例中p实际表示的是一个非常量的指针别名,但给它赋值的指针&a又是指向一个const对象,所以会发生编译错误.正确做法:

const int a = 10;
const int *const &p = &a;	//正确

2.数组的初始化

​ 数组初始化时维数值必须是常量表达式,非const的变量不能被用来指定数组的维数.

​ 如下是错误的定义方式:

int a = 10;	//因为a是非const对象,在编译时访问不了a的值,因此数组无法完成初始化,编译错误
int arr[a];

​ 正确定义应该为:

const int a = 10;
int arr[a];

​ 但任意整数值的表达式都可以用来索引数组.

3.vector插入

​ vector在初始化时,如果给定了指定大小定义vector,vector中的值则其全部初始化为0,如果此时向vector中插入值,则会在这些0后面追加值,而不是覆盖原有的0,初学者易错.如下:

vector<int> v1(5);
v1.push_back(2);
for (vector<int>::iterator vit = v1.begin(); vit < v1.end(); vit++)
{
	cout << *vit << "\t" << endl;
}

​ 最后结果是 0 0 0 0 0 2,可见其初始化后默认产生的0值没有被覆盖.

4.typedef不能当作宏扩展

​ 在下面代码示例中,str是什么类型?

typedef char *cstring;
extern const cstring str;

​ 你可能觉得是个str是个char* 类型,指向一个常量字符串,但是这样想是错误的.这里的const修饰了str,因此这是一个指向字符的const指针.等同于char *const str;

5.容器的删除元素

在使用迭代器对容器中元素进行删除时,一定要接收erase返回的迭代器,这样才能继续遍历.否则,在删除一个元素后,原来的迭代器的行进方向不再与数据吻合,因为删除一个元素后数据在内存中发生了改变,而迭代器还是按照原来的数据规则进行遍历,因此会出错!

int main()
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	list<int> ilist(ia, ia + 11);
	int count = 0;
	
	for (list<int>::iterator vit = ilist.begin(); vit != ilist.end();)
	{
		if (count % 2 == 1)
		{
			vit = ilist.erase(vit);
		}
		else
		{
			vit++;
		}
		count++;
	}
	for (list<int>::iterator vit = ilist.begin(); vit != ilist.end(); vit++)
	{
		cout << *vit << endl;
	}
	return 0;
}
上一篇:.NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary


下一篇:Repeater绑定IList类型数据