1、 C++ 定義了哪些類型轉換操作符?分別有什么作用?
① 定義了四個操作符:static_cast,const_cast,dynamic_cast和reinterpret_cast。
② static_cast:可以被用于強制類型轉換(例如,non-const對象轉換為const對象,int轉換為double,等等),它還可以用于很多這樣的轉換的反向轉換(例如,void*指針轉換為有類型指針,基類指針轉換為派生類指針)。但是它不能將一個const對象轉換為一個non-const對象(只有const-cast能做到)。它最接近于C-style的轉換。
③const_cast:一般用于強制消除對象的常量性。它是唯一能做到這一點的C++風格的強制類型。
④dynamic_cast:主要用于執行“安全的向下轉型”。也就是說,要確定一個對象是否是一個繼承體系中的一個特定類型。它是唯一不能用舊風格語法執行的強制類型轉換,也是唯一可能有重大運行時代價的強制轉換。
⑤reinterpret_cast:是特意用于底層的強制轉換,導致實現依賴(implementation-dependent)(就是說,不可移植)的結果。例如,將一個指針轉型為一個整數。這樣的強制轉換在底層代碼以外應該極為罕見。
2、 C++ 定義了哪些訪問控制關鍵字?分別有什么作用?
簡單可以歸為以下兩種描述:
1)一個類友元(包含友元函數或者友元類的成員函數或者友元類的所有成員函數)可以訪問該類的任何成員(包括成員變量及成員方法)。
2)除去友元外,private成員只有該類自身的成員函數可以訪問,protected成員只有該類及其派生類的成員函數可以訪問,public成員則該類及其派生類的成員函數和對象都可以訪問。
3、 類的繼承方式和區別?
派生類繼承方式的影響
類的繼承方式有三種:private、protected、public。
1)private屬性不能被繼承。
2)
使用private繼承,父類的protected和public屬性在子類中變為private;
使用protected繼承,父類的protected和public屬性在子類中變為protected;
使用public繼承,父類中的protected和public屬性不發生改變;
4、 在什么情形下調用虛函數不會有多態性?為什么?
由虛函數實現的動態多態性的方法:
1. 在基類用virtual聲明成員函數為虛函數。
2. 在派生類中重新定義此函數。
3. 定義一個指向基類對象的指針變量,并使它指向同一類族中需要調用該函數的對象。
4. 通過該指針變量調用此虛函數,此時調用的就是指針變量指向的對象的同名函數。
因此,總結如下:
1、基類函數未使用virtual聲明而子類中使用virtual關鍵字聲明時調用虛函數不會有多態性;
2、基類使用virtual而子類未重新實現該虛函數則不會有多態性;
3、 使用子類創建的對象轉換成基類類型調用虛函數不會有多態性;
5. 構造函數調用順序。
class Y {...}
class X : public Y {...}
X one;
構造函數的調用順序是下面的順序:
Y(); // 基類的構造函數
X(); // 繼承類的構造函數
對于多基類的情況,下面是一個例子:
class X : public Y, public Z
X one;
構造函數以聲明的次序調用。
Y(); // 基類構造函數首先被調用
Z();
X();
虛基類的構造函數在任何非虛基類構造函數前調用。如果構造中包括多個虛基類,它們的調用順序以聲明順序為準。..
如果虛類是由非虛類派生而來,那非虛類的構造函數要先被調用。下面是一個例子:
class X : public Y, virtual public Z
X one;
調用順序如下:
Z(); // 虛基類初始化
Y(); // 非虛基類
X(); // 繼承類
下面是一個復雜的例子:
class base;
class base2;
class level1 : public base2, virtual public base;
class level2 : public base2, virtual public base;
class toplevel : public level1, virtual public level2;
toplevel view;
構造函數調用順序如下:
base(); // 虛基類僅被構造一次
base2();
level2(); // 虛基類
base2();
level1();
toplevel();
如果類繼承中包括多個虛基類的實例,基類只被初始化一次。
1、如果類里面有成員類,成員類的構造函數優先被調用;
2、創建派生類的對象,基類的構造函數函數優先被調用(也優先于派生類里的成員類);
3、 基類構造函數如果有多個基類則構造函數的調用順序是某類在類派生表中出現的順序而不是它們在成員初始化表中的順序;
4、成員類對象構造函數如果有多個成員類對象則構造函數的調用順序是對象在類中被聲明的順序而不是它們出現在成員初始化表中的順序;
5、派生類構造函數
作為一般規則派生類構造函數應該不能直接向一個基類數據成員賦值而是把值傳遞給適當的基類構造函數否則兩個類的實現變成緊耦合的(tightly coupled)將更加難于正確地修改或擴展基類的實現。(基類設計者的責任是提供一組適當的基類構造函數)
6. RTTI是什么,怎么實現的?舉個例子。
RTTI即運行時類型識別,通過它程序能夠使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。
RTTI提供了一下兩個非常有用的操作符:
1、typeid操作符,返回指針和引用所指的實際類型
2、dynamic_cast操作符,將基類類型的指針或引用安全地轉換為派生類型的指針或引用。