1、在VC的MFC程序中能否使用cout輸出?
答:不能。必須使用CDC來進行輸出。
2、C++中子類的構造函數是否會自動調用基類構造函數?
答:會。如果在子類的構造函數中不顯式指定調用基類構造函數,則將自動調用基類缺省構造函數,所以基類一定要有缺省構造函數。如果子類的構造函數除了調用基類構造函數以外什麼都不做,不能不寫,必須寫一個空函數。
3、子類對象的初始化過程是怎樣的?
答:先調用基類構造函數來初始化相關的基類子對象,然後再執行子類(派生類)的構造函數。
4、名字空間的使用有哪些方式?
答:大概有三種方式:
l 使用名字空間別名加上名稱限制修飾符
namespace LIB = IBM_Canada_Laboratory;
LIB::Array<int> ia(1024);
l using指示符,使名字空間內的所有聲明可見
using namespace IBM_Canada_Laboratory;
l using聲明,使名字空間中的單個聲明可見
using IBM_Canada_Laboratory::Matrix;
using指示符和using聲明的本質是不同的。
5、如何聲明一個對象已經在文件外被定義?
答:使用extern來聲明。可以在多個地方多次聲明同一個對象,但是一個對象只能被定義一次,而且多個聲明必須明確無誤的指向這個定義實體。聲明不分配內存,定義分配內存。
6、類的缺省構造函數會爲類的數據成員初始化嗎?
答:不會。只會分配內存,不會初始化。必須在缺省構造函數中顯式進行初始化。
7、下面的對象初始化是調用賦值操作符嗎?
BaseClass base1; BaseClass base2 = base1;
答:不是。是調用拷貝構造函數。
8、類中的常量數據成員應該在哪裏被初始化?
答:應該在類的成員初始化列表中初始化。
9、typedef引入了新的類型嗎?
答:沒有。它僅僅是用來爲內置或用戶定義的數據類型引入助記符號。
10、空指針解引用會出錯嗎?
答:會。對指針解引用之前一定要先確定其不爲零。
11、算術異常會拋出實際異常嗎?
答:算術異常是指計算過程中出現不正確或未定義的值,如除以0或溢出。但是不會導致拋出實際的異常。
12、size_t是什麼類型?
答:這是用typedef引入的類型助記符,代替unsigned int。
13、用sizeof可以獲得一個數組的長度,爲什麼在傳遞數組給函數時還要帶上長度參數?
答:用sizeof是可以獲取一個數組的長度,如int a[10]; int len = sizeof(a)/sizeof(int);。但是,在用數組作爲參數傳遞給函數時,數組變爲了指針,所以在函數內部不能獲取數組長度。
14、算術轉換的指導原則是什麼?
答:有兩個通用原則:一、類型總是被提升爲較寬的類型;二、所有含有小於整型的有序類型,在計算之前,其類型都會被轉換成整型。
15、都有哪些顯式強制轉換操作符?它們的功能是什麼?
答:有static_cast、const_cast、dynamic_cast和reinterpret_cast。static_cast可用來執行任何編譯器可隱式執行的任何類型轉換。const_cast用來將常量對象或指針轉換爲非常量對象或指針。reinterpret_cast通常對於操作數的位模式執行一個比較低層次的重新解釋,相當於舊式的指針強制轉換。dynamic_cast支持在運行時刻識別由指針或引用指向的類對象。
16、對於類對象的定義爲什麼最好在用之前才定義,而不要在一開始就定義?
答:對於內置類型,它的定義只是分配內存,不會做更多的處理。而對於類對象,它的定義除了分配內存外,還要調用構造函數。因此,如果在函數或語句塊一開始就定義類對象,必然會導致構造函數的調用,而這些調用的開銷可能是不必要的。這使得程序的效率下降。因此,最好是當真正要用的時候纔去定義比較好。
17、容器類型的容量與長度的區別?
答:容量只與連續存儲的容器類相關,如vector、deque或string,而對於非連續存儲的容器類,如list,則沒有容量的概念。它是指在容器下一次需要增長自己之前能夠被加入到容器中的元素的總數,可調用capacity()操作來獲得。長度是指容器當前擁有元素的個數,可調用size()操作來獲得。容量的增長方式是與具體實現有關的。
18、迭代器的基本概念是什麼?
答:迭代器提供了一種一般化的方法,對順序或關聯容器類型中的每個元素進行連續訪問。
19、什麼時候函數應該採用引用參數?
答:一、希望改變實參的值,又不想用指針操作;二、希望返回更多的值;三、實參爲大型類對象,按值傳遞效率低。
20、函數參數表中的省略號是什麼意思?
答:省略號告訴編譯器不用對這個函數的參數進行參數類型檢查了,參數可以有0個或多個。
21、extern的用法有哪些?
答:一、鏈接指示符,用來聲明函數由其他語言編寫,如extern “C”;二、聲明一個全局變量,表示該變量在其他文件中定義了。聲明函數時可省略掉。
22、函數名和函數名取地址都可以作爲函數指針嗎?
答:可以。因此,函數指針和函數指針解引用都可以用來調用函數。
23、類型安全鏈接的含義是什麼?
答:在編譯階段,有一種機制可以把函數參數的類型和數目編碼在函數名中,該機制叫做類型安全鏈接。所以,一個函數並非僅僅通過函數名來識別的,這是函數重載的基礎。
24、靜態對象會被缺省初始化嗎?
答:會。缺省初始化爲0。
25、用delete刪除動態內存分配的空間時,是否要先判斷指針爲NULL?
答:不用,程序內部會自動判斷。但是最好在刪除之後將指針設爲NULL。
26、using聲明和using指示符的本質有什麼不同?
答:using聲明相當於在聲明的語句處引入一個別名,該別名與聲明的名稱空間中的同名對象或函數一樣。using指示符相當於把名稱空間在其定義處就地剝開,並不引入新的別名。
27、函數重載時是否考慮const參數的影響?
答:對於const對象來說,函數重載不考慮,即認爲帶有const和非const對象參數的函數是相同的函數聲明。而對於const指針或引用,則認爲是不同的函數聲明。
28、extern “c”鏈接指示符能否將c函數引入到重載函數集合中?
答:能,但只能引入一個。即c語言的函數只能有一個屬於重載函數集合。
29、函數模板實例化的過程中,模板類型參數是如何被確定類型的?
答:是通過調用函數時的實參類型來推演模板的參數類型的,該過程稱爲模板實參推演。
30、異常處理子句catch中聲明異常類對象有何用?
答:這個異常類對象可以捕獲異常發生時,由throw子句所產生異常類對象。如果改爲異常類對象的引用,則還可進一步修改由throw子句拋出的異常類對象,並重新拋出。
31、如果函數拋出了其異常規範之外的異常時會出現什麼情況?
答:系統調用C++標準庫定義的函數unexpected(),其將調用terminate()。
32、指定一個空的異常規範和不指定異常規範一樣嗎?
答:不一樣。空的異常規範表示該函數不能拋出任何異常,而不指定異常規範表示該函數可以拋出任何異常。
33、在程序設計中異常設計是否很困難?
答:是。異常是庫接口的一部分,什麼時候拋出異常,什麼時候庫自己處理,在那些調用程序中處理拋出的異常都是一個問題。
34、STL的主要組成部分包括哪些?
答:有容器類(包含數據)、算法(對數據的操作)、迭代器(連接容器和算法)以及函數對象(定義具體的操作方式)。
35、函數對象的一般用法如何?
答:一般將函數對象定義爲一個類,然後需要重載該類的調用操作符。一般的泛型算法都可以接受函數對象或函數指針。函數指針的用法缺點是不能支持函數內聯。
36、函數對象從哪裏來?
答:一、標準庫預定義的一組算術、關係和邏輯函數對象;二、定義自己的函數對象;三、一組預定義的函數適配器,對函數對象進行特殊化或者擴展。
37、什麼是函數適配器?
答:標準庫提供的一組特殊的類,用來特殊化或者擴展函數對象。它被分成下面兩類:綁定器(binder)和取反器(negator)。
38、排序算法能用在list上嗎?
答:不能,也不能用在聯合容器set或map上。
39、類在定義之前能定義類對象嗎?
答:不能。但可以先聲明這個類,然後定義該類的指針或引用。
40、聲明const成員函數時是否要在定義函數時也加上const?
答:在聲明和定義函數的時候都必須加上const。
41、const成員函數有什麼要求?
答:要求在const函數當中不能修改類的數據成員。對於那些不修改數據成員的函數最好將其聲明爲const函數。有一個例外,如果數據成員定義爲mutable類型,則在const函數中也可以修改該數據成員。
42、靜態數據成員如何初始化?
答:應該在類體定義之外初始化,但不能在類的構造函數中初始化,因爲靜態成員不屬於某個類對象,而是屬於類的。靜態數據成員可通過類的限定修飾符來訪問。
43、什麼是嵌套類?
答:在一個類A的類體中定義的另一個類B,稱爲嵌套類(nested class)。
44、如何調用類的缺省構造函數定義類對象?
答:不能這樣寫:ClassA obj(); 這樣會被認爲聲明瞭一個函數,必須這樣寫:ClassA obj;。一般情況都必須爲類提供缺省構造函數。
45、應用在構造函數上的explicit有什麼作用?
答:一般構造函數如果只含有一個參數,則編譯器可以隱式的調用該構造函數,將參數類型轉換爲類類型,但是這種隱式轉換在某些時候是存在隱患的,在構造函數前面加上explicit就是爲了防止這種隱式調用發生。
46、一個類對象的容器類是如何初始化的?
答:先創建該類的臨時對象,並用缺省構造函數初始化;然後將臨時對象通過拷貝構造函數拷貝到容器類當中的所有類對象上;然後刪除臨時對象。
47、類的成員類對象在構造函數中初始化時,放在成員初始化表中與放在構造函數體中有什麼區別?
答:實際上類的初始化分爲兩個階段,第一個階段是初始化階段,它調用所有成員類的缺省構造函數或者調用成員初始化表;第二個階段是計算階段,它調用函數體內的語句。所以如果將成員類對象放在函數體中初始化,實際上是先調用缺省構造函數,然後執行賦值操作,效率大大降低。一般準則是所有的成員類對象都應該將其放在成員初始化表中。另外對於const成員和引用成員必須在成員初始化表中。
48、拷貝構造函數和拷貝賦值操作符是一回事嗎?
答:不是。但一般來說,兩者應該同時定義或者禁止。
49、前置和後置++和--操作符函數原型有什麼不同?
答:後置的操作符函數參數比前置的操作符函數多一個int參數,該參數在函數定義中並不會使用。
50、轉換函數與構造函數都可完成類型轉換,它們有什麼區別?
答:構造函數(帶有一個參數的)可完成其它類型向該類類型轉換操作,而轉換函數是從該類類型向指定的類型轉換的操作。轉換函數原型不能含有返回值和參數。它的定義形式如下:operator type() {}。
51、用戶定義的轉換包括什麼?
答:包括調用轉換函數或一個參數的構造函數。
52、標準C++支持爲模板參數提供默認實參嗎?
答:支持,但VC++6.0不支持。
53、類模板的成員函數的實例化是不是隨着類模板的實例化進行的?
答:不是,成員函數的實例化是當函數被調用的時候才實例化的。
54、面向對象編程的基礎是什麼?
答:兩個基礎:多態(polymorphism)和動態綁定(dynamic binding)。多態指的是基類的指針或引用可以指向基類派生的任何子類,即一個基類指針或引用可能的實際類型是多種的。動態綁定指的是當用基類指針調用函數時,如果函數是虛函數(virtual function),則實際調用哪個函數是在運行時刻根據指針的實際類型來動態決定了。
55、在面向對象設計中是否一次性完成類結構設計?
答:一般很難,通常是反覆迭代,要求對不斷演化過程中的類層次結構進行添加和修改。
56、基類的一般用法如何?
答:定義基類的指針或引用(如果包含純虛函數,則不能定義抽象基類的對象),然後用它們來操縱任何從該基類派生來的子類對象。
57、面向對象基類的設計主要要考慮的問題是什麼?
答:確定哪些成員爲protected;確定哪些函數爲虛函數。
58、派生類的虛函數原型是否要指定virtual?
答:可要可不要。
59、派生類能否定義函數,以重載基類當中的函數?
答:可以。採用在派生類中使用using聲明可做到。
60、派生類的構造函數執行包括幾個步驟?
答:三個步驟:基類構造函數;成員類構造函數;派生類構造函數。
61、類的構造函數的訪問權限只能是public嗎?
答:不是。可以是protected和private兩種。當構造函數爲protected時,只希望在派生類中構造該類。當構造函數爲private時,不希望任何地方來構造該類,如果有友元類,可以在友元類中構造該類。
62、派生類的構造函數要調用基類的缺省構造函數,是否要顯式調用?
答:不用。會被隱式調用。
63、析構函數是否也可以做成動態綁定?
答:可以,只要聲明爲虛函數。
64、虛擬函數在.cpp文件中定義時是否要加virtual?
答:不能加。
65、如何靜態調用虛擬函數?
答:用類域限定符。
66、clone函數是幹什麼的?
答:是用來克隆一個類對象,並返回克隆後的對象指針。
67、dynamic_cast是幹什麼用的?
答:它是RTTI(運行時刻類型識別)的一部分。它支持在運行時刻查詢一個多態指針或引用所指向的對象的實際類型。
68、多繼承下的多個基類一般與派生類存在什麼關係?
答:一般每個基類代表派生類完整接口的一個方面。
69、private繼承意味着什麼?
答:由於基類的所有成員(public和protected成員)都變成子類的private成員,包括基類的公共接口也變成私有的了,因此,子類不能給外部直接提供基類的公共接口,而必須重新實現它們。這往往是由於子類僅僅希望得到基類的數據成員,但不希望繼承基類的接口。
70、什麼是RTTI?
答:運行時刻類型識別,可使得程序可以知道指向基類的指針或引用實際所指的對象的類型。它提供了兩個操作符:dynamic_cast,允許在運行時刻進行類型轉換,把基類指針轉換成派生類指針;typeid,指出指針或引用的實際派生類型。
71、typeid操作符如何使用?
答:typeid的參數如爲類對象,則返回該類對象的實際類型。如爲類指針,則返回該指針的定義類型。返回的值實際上是一個type_info類。
72、類成員函數的聲明和定義中都要指定異常規範嗎?
答:都要。