基础知识点 | 1025_关于初始化,初始化列表和union类的常错题
1.初始化时的问题
// 代码如下,问哪一句会出错?
char* s="AAA"; //1
printf("%s",s); //2
s[0]='B'; //3
printf("%s",s); //4
- 第三句处出错,原因在于,初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。
- 第一句处定义了一个指针s,指向一块常量区"AAA"的地址,所以修改 *s 是不合法的;如果定义成了
char s[] = "AAA",就可以修改了。
2.构造函数中的初始化列表
// 代码如下,输出 B1 1&B2&B1 2&B2&C 3,要求填写________
class B1 {
public:
B1(int i) {
cout << "B1" << " " << i << "&";
}
};
class B2 {
public:
B2() {
cout << "B2" << "&";
}
};
class C : public B1, public B2
{
public:
C(int a, int b, int c) : ________ {
indiv = c;
cout << "C" << " " << indiv;
}
private:
B1 m1;
B2 m2;
int indiv;
};
int main() {
C c(1, 2, 3);
return 0;
}
首先分析类B1和B2的构造函数:
- B1有显式的构造函数且有参数,因此构造B1时必须使用带参形式
B1 ( i );- B2有显式的构造函数但是无参数,因此构造B2可以使用
B2 b2()或B2 b2,两者均调用显示定义的构造函数;其次分析类C:
- C有两个基类B1、B2,因此首先需要执行B1和B2的构造函数;
- C有两个成员对象m1,m2,因此需要分别执行B1和B2对这两个对象进行初始化;
所以按顺序执行以下构造函数B1 -> B2 -> B1 -> B2 -> C;
观察输出结果B1 1&B2&B1 2&B2&C 3与前面结论相符;考虑输出中的1和2 两个参数值,所以带参构造顺序如下:
B1(1) -> B2() -> B1(2) -> B2() -> C(1,2,3)
最后结合以上两点分析结果:
将B2的构造函数省略即可得到 B1(a), m1(b)
3.一直在错的题
// 代码如下,X定义如下,问输出是什么
union X{
int x;
char y[4];
};
int main() {
X a;
a.x=0x11223344;
cout << a.y[1];
return 0;
}
- union类中的类型共享一段内存
- 根据机器的不同,内存的存储方式分为 大端法 和小端法
- 所以 a.y[1] 可能取到 0x22 或者 0x33

浙公网安备 33010602011771号