《c++编程思想》阅读笔记(5)
这是第4章初始化与清除 , 的第一个补充,包括一些不是构造和析构函数的内容。。。
1)c++中的for循环计数
在c++中,我们将经常看到for循环的计数器直接在for表达式中定义:
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
上述声明是一种重要的特殊情况,这可能是那些刚接触c++的程序员感到迷惑不解。
变量i是在for表达式中直接定义的(在c中我们不能这样做),然后它就作为一个变量在for循环中使用。这给程序员带来很大的方便,因为从上下文中我们可以很清楚地知道变量i的作用,所以不必再用诸如i_loop_counter之类的名字来定义一个变量,以表示这个变量的作用。
这里有一个变量生存期的问题,这以前这是有程序块的右大括号来确定的。而作为程序员,我们显然想让i只在循环内部有效。因而在新的标准的c++说明书上说,一个在for循环的控制表达式中定义的循环技术器只在该循环内才有效,所以上面的声明是可行的。
2)switch语句可能跳过构造函数的调用点
switch语句可能跳过构造函数的调用点,然而这个对象会在后面的程序块中起作用,这样,构造函数就没有被调用,所以编译器给出了一条出错信息。这就确保了对象在产生的同时被初始化。eg:
switch(i) {
case 1 :
X x2; // constructor called here
break;
case 2 : // Error: case bypasses init
X x3;
break;
}
(然后后面的代码中出现了关于x2 的使用情况,那么就有可能出现x2 在前面没有被定义就被使用了)
3)集合初始化
集合,就是多个事物聚集在一起。这个定义包括各种类型的集合:像struct和class等。数组就是单一类型的集合。
初始化集合往往既冗长又容易出错。而c++中集合的初始化却变得方便而且很安全。当我们产生一个个集合对象时,我们要做的只是指定初始值就行了,然后初始化工作就由编译器去承担了。
数组有一种叫自动计数的快速初始化方法,就是让编译器按初始化值的个数去决定数组的大小:
int c[] = {1, 2, 3, 4};
然后,用表达式
sizeof c / sizeof *c (整个数组的大小除以第一个元素的大小)即可算出这个数组的大小。eg:
for (int i = 0; i < sizeof(c) / sizeof (*c); i++);
现在,如果我们决定增加其他的元素到这个数组上,只要增加一个初始化的值即可。如果以此建立我们的代码,只需要在一处做出修改即可。这样,我们在修改时出错的机会就减少了.
如何构造类的集合呢?
我们必须指示构造函数调用,最好的方法像下面这样:
class Y {
private:
float f;
int i;
public:
Y(int A); // presumably assigned to i
};
Y y2[] = {Y[1], Y[2], Y[3]};
这样我们就得到了三个对象和进行了三次构造函数调用。只要有构造函数,无论是所有成员都是公共的struct还是一个带有私有成员的class,所有初始化工作都必须通过构造函数,即使我们正在对一个集合初始化。
另外一个例子:
class X {
int i, j;
public :
X(int I, int J) {
i = I;
j = J;
}
};
int main() {
X xx[] = {X(1, 2), X(3, 4), X(5, 6), X(7, 8)};
return 0;
}
注意,它看上去就像数组中的每个对象都对一个没有命名的构造函数调用了一次一样