后臺(tái)開發(fā)常見面試題-- c++

static

控制變量的存儲(chǔ)方式和可見性。

  • 修飾局部變量
    一般情況下,對(duì)于局部變量是存放在棧區(qū)的,并且局部變量的生命周期在該語句塊執(zhí)行結(jié)束時(shí)便結(jié)束了。但是如果用static進(jìn)行修飾的話,該變量便存放在靜態(tài)數(shù)據(jù)區(qū),其生命周期一直持續(xù)到整個(gè)程序執(zhí)行結(jié)束。但是在這里要注意的是,雖然用static對(duì)局部變量進(jìn)行修飾過后,其生命周期以及存儲(chǔ)空間發(fā)生了變化,但是其作用域并沒有改變,其仍然是一個(gè)局部變量,作用域僅限于該語句塊。

  • 修飾全局變量
    對(duì)于一個(gè)全局變量,它既可以在本源文件中被訪問到,也可以在同一個(gè)工程的其它源文件中被訪問(只需用extern進(jìn)行聲明即可)。用static對(duì)全局變量進(jìn)行修飾改變了其作用域的范圍,由原來的整個(gè)工程可見變?yōu)楸驹次募梢姟?/strong>

  • 修飾函數(shù)
    用static修飾函數(shù)的話,情況與修飾全局變量大同小異,就是改變了函數(shù)的作用域。

  • C++中的static
    如果在C++中對(duì)類中的某個(gè)函數(shù)用static進(jìn)行修飾,則表示該函數(shù)屬于一個(gè)類而不是屬于此類的任何特定對(duì)象;如果對(duì)類中的某個(gè)變量進(jìn)行static修飾,表示該變量為類以及其所有的對(duì)象所有。它們?cè)诖鎯?chǔ)空間中都只存在一個(gè)副本??梢酝ㄟ^類和對(duì)象去調(diào)用。
    1)類的靜態(tài)成員:
    在cpp中必須對(duì)他進(jìn)行初始化,初始化時(shí)使用作用域運(yùn)算符來標(biāo)明他所屬類,其屬于該類的所有成員共有,只有一個(gè)拷貝;
    2)類的靜態(tài)成員函數(shù):
    類的靜態(tài)函數(shù)是該類的范疇內(nèi)的全局函數(shù),不能訪問類的私有成員,只能訪問類的靜態(tài)成員,不需要類的實(shí)例即可調(diào)用;實(shí)際上,他就是增加了類的訪問權(quán)限的全局函數(shù)

const的含義及實(shí)現(xiàn)機(jī)制

const名叫常量限定符,用來限定特定變量,以通知編譯器該變量是不可修改的。習(xí)慣性的使用const,可以避免在函數(shù)中對(duì)某些不應(yīng)修改的變量造成可能的改動(dòng)。

const修飾基本數(shù)據(jù)類型

  • const修飾一般常量及數(shù)組
    基本數(shù)據(jù)類型,修飾符const可以用在類型說明符前,也可以用在類型說明符后,其結(jié)果是一樣的。在使用這些常量的時(shí)候,只要不改變這些常量的值便好。

  • const修飾指針變量及引用變量&
    如果const位于星號(hào)
    的左側(cè),則const就是用來修飾指針?biāo)赶虻淖兞?,即指針指向?yàn)槌A浚?br> 如果const位于星號(hào)的右側(cè),const就是修飾指針本身,即指針本身是常量。

const應(yīng)用到函數(shù)中

  • 作為參數(shù)的const修飾符
    調(diào)用函數(shù)的時(shí)候,用相應(yīng)的變量初始化const常量,則在函數(shù)體中,按照const所修飾的部分進(jìn)行常量化,保護(hù)了原對(duì)象的屬性。
    [注意]:參數(shù)const通常用于參數(shù)為指針或引用的情況;

  • 作為函數(shù)返回值的const修飾符
    聲明了返回值后,const按照"修飾原則"進(jìn)行修飾,起到相應(yīng)的保護(hù)作用。

  • const在類中的用法
    不能在類聲明中初始化const數(shù)據(jù)成員。正確的使用const實(shí)現(xiàn)方法為:const數(shù)據(jù)成員的初始化只能在類構(gòu)造函數(shù)的初始化表中進(jìn)行

  • const 修飾類成員函數(shù),其目的是防止成員函數(shù)修改被調(diào)用對(duì)象的值,如果我們不想修改一個(gè)調(diào)用對(duì)象的值,所有的成員函數(shù)都應(yīng)當(dāng)聲明為const成員函數(shù)。 其意義上是不能修改所在類的的任何變量。注意:const關(guān)鍵字不能與static關(guān)鍵字同時(shí)使用,因?yàn)閟tatic關(guān)鍵字修飾靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)不含有this指針,即不能實(shí)例化,const成員函數(shù)必須具體到某一實(shí)例。

  • const修飾類對(duì)象,定義常量對(duì)象
    常量對(duì)象只能調(diào)用常量函數(shù),別的成員函數(shù)都不能調(diào)用。
    http://www.cnblogs.com/wintergrass/archive/2011/04/15/2015020.html
    1)const成員函數(shù)可以訪問非const對(duì)象的非const數(shù)據(jù)成員、const數(shù)據(jù)成員,也可以訪問const對(duì)象內(nèi)的所有數(shù)據(jù)成員;
    2)非const成員函數(shù)可以訪問非const對(duì)象的非const數(shù)據(jù)成員、const數(shù)據(jù)成員,但不可以訪問const對(duì)象的任意數(shù)據(jù)成員;
    3)作為一種良好的編程風(fēng)格,在聲明一個(gè)成員函數(shù)時(shí),若該成員函數(shù)并不對(duì)數(shù)據(jù)成員進(jìn)行修改操作,應(yīng)盡可能將該成員函數(shù)聲明為const 成員函數(shù)。

static, const 和 static const 變量的初始化問題

  • const 常量的在超出其作用域的時(shí)候會(huì)被釋放,但是 static 靜態(tài)變量在其作用域之外并沒有釋放,只是不能訪問。

  • static 修飾的是靜態(tài)變量,靜態(tài)函數(shù)。對(duì)于類來說,靜態(tài)成員和靜態(tài)函數(shù)是屬于整個(gè)類的,而不是屬于對(duì)象??梢酝ㄟ^類名來訪問,但是其作用域限制于包含它的文件中。

  • static 變量在類內(nèi)部聲明,但是必須在類的外部進(jìn)行定義和初始化。

  • const 常量在類內(nèi)部聲明,但是定義只能在構(gòu)造函數(shù)的初始化列表進(jìn)行。

虛函數(shù): 虛函數(shù)的作用和實(shí)現(xiàn)原理,什么是虛函數(shù),有什么作用?

C++的多態(tài)分為靜態(tài)多態(tài)(編譯時(shí)多態(tài))和動(dòng)態(tài)多態(tài)(運(yùn)行時(shí)多態(tài))兩大類。靜態(tài)多態(tài)通過重載、模板來實(shí)現(xiàn);動(dòng)態(tài)多態(tài)就是通過本文的主角虛函數(shù)來體現(xiàn)的。

  • 虛函數(shù)實(shí)現(xiàn)原理:包括虛函數(shù)表、虛函數(shù)指針
    虛函數(shù)就是對(duì)父類同名函數(shù)的重寫。在成員函數(shù)聲明前面加上virtual修飾,就變成了虛函數(shù)。調(diào)用函數(shù)的哪個(gè)版本只有在運(yùn)行時(shí)才能確定(動(dòng)態(tài)綁定),因此需要虛函數(shù)表,也就導(dǎo)致虛函數(shù)會(huì)比普通函數(shù)成員所花費(fèi)的時(shí)間和空間要多一些。
    虛函數(shù)的作用說白了就是:當(dāng)調(diào)用一個(gè)虛函數(shù)時(shí),被執(zhí)行的代碼必須和調(diào)用函數(shù)的對(duì)象的動(dòng)態(tài)類型相一致。編譯器需要做的就是如何高效的實(shí)現(xiàn)提供這種特性。不同編譯器實(shí)現(xiàn)細(xì)節(jié)也不相同。大多數(shù)編譯器通過vtbl(virtual table)和vptr(virtual table pointer)來實(shí)現(xiàn)的。 當(dāng)一個(gè)類聲明了虛函數(shù)或者繼承了虛函數(shù),這個(gè)類就會(huì)有自己的vtbl。vtbl實(shí)際上就是一個(gè)函數(shù)指針數(shù)組,有的編譯器用的是鏈表,不過方法都是差不多。vtbl數(shù)組中的每一個(gè)元素對(duì)應(yīng)一個(gè)函數(shù)指針指向該類的一個(gè)虛函數(shù),同時(shí)該類的每一個(gè)對(duì)象都會(huì)包含一個(gè)vptr,vptr指向該vtbl的地址。

虛函數(shù)不能是構(gòu)造函數(shù),不能是靜態(tài)函數(shù),不能是內(nèi)聯(lián)函數(shù),可以是析構(gòu)函數(shù)。

  • 結(jié)論
    1)每個(gè)聲明了虛函數(shù)或者繼承了虛函數(shù)的類,都會(huì)有一個(gè)自己的vtbl,同時(shí)該類的每個(gè)對(duì)象都會(huì)包含一個(gè)vptr去指向該vtbl
    2)虛函數(shù)按照其聲明順序放于vtbl表中, vtbl數(shù)組中的每一個(gè)元素對(duì)應(yīng)一個(gè)函數(shù)指針指向該類的虛函數(shù)
    3)如果子類覆蓋了父類的虛函數(shù),將被放到了虛表中原來父類虛函數(shù)的位置
    4)在多繼承的情況下,每個(gè)父類都有自己的虛表。子類的成員函數(shù)被放到了第一個(gè)父類的表中

C++中引用和指針的區(qū)別

它們都是地址的概念,其中指針指向一塊內(nèi)存,它的內(nèi)容是所指內(nèi)存的地址;而引用是某塊內(nèi)存的別名,具體來說,指針是一個(gè)變量的地址,引用是一個(gè)變量的別名。
但它們的不同之處也很明顯,體現(xiàn)在以下方面:

  • 指針是一個(gè)實(shí)體,而引用僅是個(gè)別名;
  • 引用必須被初始化,指針不必;
  • 引用只能在定義時(shí)被初始化一次,之后不可變;指針可以改變所指的對(duì)象;
  • 可以有const指針,但是沒有const引用;
  • 不存在指向空值的引用,但是存在指向空值的指針,即引用不能為空,指針可以為空;
  • “sizeof 引用”得到的是所指向的變量(對(duì)象)的大小,而“sizeof 指針”得到的是指針本身(所指向的變量或?qū)ο蟮牡刂罚┑拇笮。?/li>
  • 指針和引用的自增(++)運(yùn)算意義不一樣;
  • 程序?yàn)橹羔樧兞糠峙鋬?nèi)存區(qū)域,而引用不需要分配內(nèi)存區(qū)域;

內(nèi)存分配:

  • 內(nèi)存分配方式有三種:
    (1)從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。
    (2)在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
    (3)從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。 程序在運(yùn)行的時(shí)候用malloc或new申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問題也最多。

STL原理及實(shí)現(xiàn): STL各類型容器實(shí)現(xiàn),STL共有六大組件

STL提供六大組件,彼此可以組合套用:

  1. 容器(Containers):各種數(shù)據(jù)結(jié)構(gòu),如:序列式容器vector、list、deque、關(guān)聯(lián)式容器set、map、multiset、multimap。用來存放數(shù)據(jù)。從實(shí)現(xiàn)的角度來看,STL容器是一種class template。
  2. 算法(algorithms):各種常用算法,如:sort、search、copy、erase。從實(shí)現(xiàn)的角度來看,STL算法是一種 function template。注意一個(gè)問題:任何的一個(gè)STL算法,都需要獲得由一對(duì)迭代器所標(biāo)示的區(qū)間,用來表示操作范圍。這一對(duì)迭代器所標(biāo)示的區(qū)間都是前閉后開區(qū)間,例如[first, last)
  3. 迭代器(iterators):容器與算法之間的膠合劑,是所謂的“泛型指針”。共有五種類型,以及其他衍生變化。從實(shí)現(xiàn)的角度來看,迭代器是一種將 operator*、operator->、operator++、operator- - 等指針相關(guān)操作進(jìn)行重載的class template。所有STL容器都有自己專屬的迭代器,只有容器本身才知道如何遍歷自己的元素。原生指針(native pointer)也是一種迭代器。
  4. 仿函數(shù)(functors):行為類似函數(shù),可作為算法的某種策略(policy)。從實(shí)現(xiàn)的角度來看,仿函數(shù)是一種重載了operator()的class或class template。一般的函數(shù)指針也可視為狹義的仿函數(shù)。
  5. 配接器(adapters):一種用來修飾容器、仿函數(shù)、迭代器接口的東西。例如:STL提供的queue 和 stack,雖然看似容器,但其實(shí)只能算是一種容器配接器,因?yàn)樗鼈兊牡撞客耆柚鷇eque,所有操作都由底層的deque供應(yīng)。改變 functors接口者,稱為function adapter;改變 container 接口者,稱為container adapter;改變iterator接口者,稱為iterator adapter。
  6. 配置器(allocators):負(fù)責(zé)空間配置與管理。從實(shí)現(xiàn)的角度來看,配置器是一個(gè)實(shí)現(xiàn)了動(dòng)態(tài)空間配置、空間管理、空間釋放的class template。

這六大組件的交互關(guān)系:container(容器) 通過 allocator(配置器) 取得數(shù)據(jù)儲(chǔ)存空間,algorithm(算法)通過 iterator(迭代器)存取 container(容器) 內(nèi)容,functor(仿函數(shù)) 可以協(xié)助 algorithm(算法) 完成不同的策略變化,adapter(配接器) 可以修飾或套接 functor(仿函數(shù))

  • 序列式容器:
  1. vector-數(shù)組,元素不夠時(shí)再重新分配內(nèi)存,拷貝原來數(shù)組的元素到新分配的數(shù)組中。
  2. list-單鏈表。
  3. deque-分配中央控制器map(并非map容器),map記錄著一系列的固定長度的數(shù)組的地址.記住這個(gè)map僅僅保存的是數(shù)組的地址,真正的數(shù)據(jù)在數(shù)組中存放著.deque先從map中央的位置(因?yàn)殡p向隊(duì)列,前后都可以插入元素)找到一個(gè)數(shù)組地址,向該數(shù)組中放入數(shù)據(jù),數(shù)組不夠時(shí)繼續(xù)在map中找空閑的數(shù)組來存數(shù)據(jù)。當(dāng)map也不夠時(shí)重新分配內(nèi)存當(dāng)作新的map,把原來map中的內(nèi)容copy的新map中。所以使用deque的復(fù)雜度要大于vector,盡量使用vector。
  4. stack-基于deque。
  5. queue-基于deque。
  6. heap-完全二叉樹,使用最大堆排序,以數(shù)組(vector)的形式存放。
  7. priority_queue-基于heap。
  8. slist-雙向鏈表。
  • 關(guān)聯(lián)式容器:
    • set,map,multiset,multimap-基于紅黑樹(RB-tree),一種加上了額外平衡條件的二叉搜索樹。
    • hash table-散列表。將待存數(shù)據(jù)的key經(jīng)過映射函數(shù)變成一個(gè)數(shù)組(一般是vector)的索引,例如:數(shù)據(jù)的key%數(shù)組的大?。綌?shù)組的索引(一般文本通過算法也可以轉(zhuǎn)換為數(shù)字),然后將數(shù)據(jù)當(dāng)作此索引的數(shù)組元素。有些數(shù)據(jù)的key經(jīng)過算法的轉(zhuǎn)換可能是同一個(gè)數(shù)組的索引值(碰撞問題,可以用線性探測(cè),二次探測(cè)來解決),STL是用開鏈的方法來解決的,每一個(gè)數(shù)組的元素維護(hù)一個(gè)list,他把相同索引值的數(shù)據(jù)存入一個(gè)list,這樣當(dāng)list比較短時(shí)執(zhí)行刪除,插入,搜索等算法比較快。
    • hash_map,hash_set,hash_multiset,hash_multimap-基于hashtable。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容