基礎知識點 | 1025_關於初始化,初始化列表和union類的常錯題
阿新 • • 發佈:2021-10-25
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