應(yīng)用敏捷與安全如何兼存?
969
2025-03-31
1、什么是static關(guān)鍵字?
我心想,這還不簡單嗎?聲明靜態(tài)變量、函數(shù)的關(guān)鍵字啊。然后我就這么說了,然后就沒然后了。
事后,我看了一下標(biāo)準(zhǔn)回答,大致是這樣的,我復(fù)述一遍,不然就被舉報抄襲了。
1、在變量前加上該關(guān)鍵字,變量就變成了靜態(tài)變量。 2、未經(jīng)初始化的靜態(tài)變量默認(rèn)為0。 3、靜態(tài)變量存儲在靜態(tài)存儲區(qū),在整個程序運行的過程中一直存在。 4、如果是全局靜態(tài)變量,則只在聲明它的文件中可見,準(zhǔn)確的說,是從聲明開始,到文件結(jié)束。 5、如果是局部靜態(tài)變量,作用域仍是局部作用域。 但是當(dāng)作用域結(jié)束,局部靜態(tài)變量依舊保存在靜態(tài)存儲區(qū)中,只是我們無法訪問,直到函數(shù)再次被調(diào)用,其值不變。 6、靜態(tài)函數(shù)。靜態(tài)函數(shù)的定義和聲明默認(rèn)都是extern的。 7、函數(shù)的實現(xiàn)使用static修飾,那么這個函數(shù)只可在本cpp內(nèi)使用,不會同其他cpp中的同名函數(shù)引起沖突。 8、不要再頭文件中聲明static的全局函數(shù),不要在源文件內(nèi)聲明非static的全局函數(shù)。 9、類的靜態(tài)成員。在類中,靜態(tài)成員可以實現(xiàn)多個對象之間的數(shù)據(jù)共享,而且還安全。對多個對象來說,靜態(tài)數(shù)據(jù)成員只存儲一處,供所有對象共用。 10、靜態(tài)成員函數(shù)和靜態(tài)數(shù)據(jù)成員一樣,它們都屬于類的靜態(tài)成員,它們**都不是對象成員**。因此,對靜態(tài)成員的引用不需要用對象名。
1
2
3
4
5
6
7
8
9
10
11
夠多吧,我頂多答了三四條。
2、什么是野指針?
好,我巴拉巴拉的講了一大堆,順帶還扯上了智能指針,雖然我也沒用過智能指針。
野指針就是指向一個已刪除的對象或者未申請訪問受限內(nèi)存區(qū)域的指針
1
以上是我碰到過的,以下是我還沒碰到的(我總不能每一題都在無準(zhǔn)備情況下作答吧!!!)
3、說一說c++中四種cast轉(zhuǎn)換
說實話,cast轉(zhuǎn)換我只用過幾次,我只知道它跟const脫不了干系。
1、const_cast 用于將const變量轉(zhuǎn)為非const 2、static_cast 用于各種隱式轉(zhuǎn)換,比如非const轉(zhuǎn)const,void*轉(zhuǎn)指針等 3、dynamic_cast(不是很懂) 用于動態(tài)類型轉(zhuǎn)換。只能用于含有虛函數(shù)的類。 向上轉(zhuǎn)換:指的是子類向基類的轉(zhuǎn)換 向下轉(zhuǎn)換:指的是基類向子類的轉(zhuǎn)換 4、reinterpret_cast(這個更沒聽說過了) 幾乎什么都可以轉(zhuǎn),比如將int轉(zhuǎn)指針,可能會出問題,盡量少用; 5、為什么不使用C的強(qiáng)制轉(zhuǎn)換? C的強(qiáng)制轉(zhuǎn)換表面上看起來功能強(qiáng)大什么都能轉(zhuǎn),但是轉(zhuǎn)化不夠明確,不能進(jìn)行錯誤檢查,容易出錯。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
看這里:
我珍藏很久的了。
4、 請說一下C/C++ 中指針和引用的區(qū)別?
1、指針有自己的一塊兒空間,而引用只是個別名。使用sizeof看一個指針的大小是4,而引用則是被引用對象的大小; 2、指針可以被初始化為NULL,而引用必須被初始化且必須是一個已有對象的引用; 3、指針在使用中可以指向其它對象,但是引用只能是一個對象的引用,不能被改變;
1
2
3
5、智能指針
C++智能指針
當(dāng)兩個對象相互使用一個shared_ptr成員變量指向?qū)Ψ剑瑫斐裳h(huán)引用,使引用計數(shù)失效,從而導(dǎo)致內(nèi)存泄漏。
6、請你來說一下C++中的智能指針
雖然天天跟人家扯皮說智能指針,但是讓我真刀真槍的干,我只能說,還沒干過。
C++里面有四種智能指針:auto_ptr(已棄用),shared_ptr, weak_ptr, unique_ptr
unique_ptr:顧名思義,這個指針是獨一無二的,屬于獨占式指針,同一時間內(nèi)指向同一資源的最多只有一個指針而已。它對于避免資源泄露非常有用。
unique_ptr
1
2
3
4
5
編譯器認(rèn)為這種寫法是非法的,避免了p1指向無效資源的問題。
shared_ptr
和unique相對的,shared實現(xiàn)的是共享式擁有。同一時間可以有多個智能指針指向同一資源。該資源會在最后一個指向其的指針銷毀時被釋放。通過計數(shù)機(jī)制來紀(jì)錄當(dāng)前有多少指針指向同一資源,可以通過成員函數(shù)use_count()來查看資源的所有者個數(shù)。
當(dāng)我們調(diào)用release()時,當(dāng)前指針會釋放資源所有權(quán),計數(shù)減一。當(dāng)計數(shù)等于0時,資源會被釋放。
weak_ptr
weak_ptr 設(shè)計的目的是為配合 shared_ptr 而引入的一種智能指針來協(xié)助 shared_ptr 工作,它只可以從一個 shared_ptr 或另一個 weak_ptr 對象構(gòu)造,它的構(gòu)造和析構(gòu)不會引起引用記數(shù)的增加或減少。weak_ptr是用來解決shared_ptr相互引用時的死鎖問題。
其可以檢測到所管理的對象是否已經(jīng)被釋放,從而避免非法訪問。
注意的是我們不能通過weak_ptr直接訪問對象的方法,比如A對象中有一個方法print(),我們不能這樣訪問,pa->pb_->print(); 英文pb_是一個weak_ptr,應(yīng)該先把它轉(zhuǎn)化為shared_ptr,如:shared_ptr p = pa->pb_.lock(); p->print();
7、為什么基類的析構(gòu)函數(shù)必須是虛函數(shù)?為什么C++默認(rèn)的析構(gòu)函數(shù)不是虛函數(shù)?
如果基類的析構(gòu)函數(shù)不是虛函數(shù),那么當(dāng)使用基類指針指向子類對象的時候,會造成子類對象無法釋放,造成內(nèi)存泄漏。
默認(rèn)析構(gòu)函數(shù)是虛函數(shù)啊,因為虛函數(shù)會使用到虛表,是要占用內(nèi)存的。能省就省吧。
8、請你來說一下函數(shù)指針
這題我自我感覺答得還不錯了。畢竟之前給人家上課的時候因為這個點尷尬了一會兒。
函數(shù)指針本身首先是一個指針,該指針指向一個具體的函數(shù)。
在調(diào)用函數(shù)指針時,是不能再函數(shù)指針名后帶上括號的,所以函數(shù)指針?biāo)鑵?shù)也需要作為參數(shù)傳入調(diào)用函數(shù)中。
9、請你來說一下靜態(tài)函數(shù)和虛函數(shù)的區(qū)別
我是真不知道這倆還有啥共同點?
靜態(tài)函數(shù)在編譯的時候就已經(jīng)確定運行時機(jī),虛函數(shù)在運行的時候動態(tài)綁定。虛函數(shù)因為用了虛函數(shù)表機(jī)制,調(diào)用的時候會增加一次內(nèi)存開銷。
10、請你說一說你理解的虛函數(shù)和多態(tài)
多態(tài)的實現(xiàn)主要分為靜態(tài)多態(tài)和動態(tài)多態(tài),靜態(tài)多態(tài)主要是重載,在編譯的時候就已經(jīng)確定;動態(tài)多態(tài)是用虛函數(shù)機(jī)制實現(xiàn)的,在運行期間動態(tài)綁定。
11、請你來回答一下const修飾成員函數(shù)的目的是什么?
表明函數(shù)調(diào)用不會對對象做出任何更改,事實上,如果確認(rèn)不會對對象做更改,就應(yīng)該為函數(shù)加上const限定,這樣無論const對象還是普通對象都可以調(diào)用該函數(shù)。
12、以下四行代碼的區(qū)別是什么? const char * arr = “123”; char * brr = “123”; const char crr[] = “123”; char drr[] = “123”;
這題是真的比較繞一些了。
const char * arr = “123”;
//字符串123保存在常量區(qū),const本來是修飾arr指向的值不能通過arr去修改,但是字符串“123”在常量區(qū),本來就不能改變,所以加不加const效果都一樣
char * brr = “123”;
//字符串123保存在常量區(qū),這個arr指針指向的是同一個位置,同樣不能通過brr去修改"123"的值
const char crr[] = “123”;
//這里123本來是在棧上的,但是編譯器可能會做某些優(yōu)化,將其放到常量區(qū)
char drr[] = “123”;
//字符串123保存在棧區(qū),可以通過drr去修改
13、說一說C++函數(shù)棧空間的最大值
默認(rèn)是1M,不過可以調(diào)整。
14、請你來說一說extern“C”
C++調(diào)用C函數(shù)需要extern C,因為C語言沒有函數(shù)重載。
15、請你回答一下new/delete與malloc/free的區(qū)別是什么 ?
1、new/delete是C++的關(guān)鍵字,而malloc/free是C語言的庫函數(shù)。
2、后者使用必須指明申請內(nèi)存空間的大小,對于類類型的對象,后者不會調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
16、請你說說虛函數(shù)表具體是怎樣實現(xiàn)運行時多態(tài)的?
說真的,這個還真沒了解過。
子類若重寫父類虛函數(shù),虛函數(shù)表中,該函數(shù)的地址會被替換,對于存在虛函數(shù)的類的對象,在VS中,對象的對象模型的頭部存放指向虛函數(shù)表的指針,通過該機(jī)制實現(xiàn)多態(tài)。
17、請你說說C語言是怎么進(jìn)行函數(shù)調(diào)用的?
每一個函數(shù)調(diào)用都會分配函數(shù)棧,在棧內(nèi)進(jìn)行函數(shù)執(zhí)行過程。調(diào)用前,先把返回地址壓棧,然后把當(dāng)前函數(shù)的esp指針壓棧。
參數(shù)壓棧順序:從右到左。
18、請你說說C++如何處理返回值?
生成一個臨時變量,把它的引用作為函數(shù)參數(shù)傳入函數(shù)內(nèi)。
19、純虛函數(shù)和虛函數(shù)的區(qū)別
1、定義方式的不同。
純虛函數(shù):virtual void func() = 0; 虛函數(shù):virtual void func();
1
2
2、含有純虛函數(shù)的類稱為抽象類,如果一個類中含有純虛函數(shù),那么任何試圖對該類進(jìn)行實例化的語句都將導(dǎo)致錯誤的產(chǎn)生,因為抽象基類(ABC)是不能被直接調(diào)用的。必須被子類繼承重載以后,根據(jù)要求調(diào)用其子類的方法。
3、虛函數(shù)可以被直接使用,也可以被子類(sub class)重載以后以多態(tài)的形式調(diào)用,而純虛函數(shù)必須在子類(sub class)中實現(xiàn)該函數(shù)才可以使用,因為純虛函數(shù)在基類(base class)只有聲明而沒有定義。
4、在虛函數(shù)和純虛函數(shù)的定義中不能有static標(biāo)識符,原因很簡單,被static修飾的函數(shù)在編譯時候要求前期bind,然而虛函數(shù)卻是動態(tài)綁定(run-time bind),而且被兩者修飾的函數(shù)生命周期(life recycle)也不一樣。
接下來繼續(xù)把基礎(chǔ)相關(guān)的過一下,操作系統(tǒng)之類的后面有安排,循序漸進(jìn)嘛。
20、請你來說一下map和set有什么區(qū)別,分別又是怎么實現(xiàn)的?
(1)map中的元素是key-value(關(guān)鍵字—值)對;Set與之相對就是關(guān)鍵字的簡單集合,set中每個元素只包含一個關(guān)鍵字。
(2)set的迭代器是const的,不允許修改元素的值;map允許修改value,但不允許修改key。
map和set是根據(jù)關(guān)鍵字排序來保證其有序性的,如果允許修改key的話,那么首先需要刪除該鍵,然后調(diào)節(jié)平衡,再插入修改后的鍵值,調(diào)節(jié)平衡,如此一來,嚴(yán)重破壞了map和set的結(jié)構(gòu),導(dǎo)致iterator失效。
(3)map支持下標(biāo)操作,set不支持下標(biāo)操作。
set 底層是通過紅黑樹(RB-tree)來實現(xiàn)的。又由于 set 所開放的各種操作接口,RB-tree 也都提供了,所以幾乎所有的 set 操作行為,都只有轉(zhuǎn)調(diào)用 RB-tree 的操作行為而已。
map也是如此。
21、請你來說一說STL迭代器刪除元素
這個問題啊,其實已經(jīng)說過很多遍了,在C++里面說過,在Python里面也說過。
1.對于序列容器vector,deque來說,使用erase(itertor)后,會出現(xiàn)各種各樣的問題,比方說出現(xiàn)野指針、foreach中刪除啊等的,反正這樣寫就好:
vector
1
2
3
4
5
6
7
8
9
10
11
12
2.對于關(guān)聯(lián)容器map set來說,使用了erase(iterator)后,當(dāng)前元素的迭代器失效,但是其結(jié)構(gòu)是紅黑樹,刪除當(dāng)前元素的,不會影響到下一個元素的迭代器,所以在調(diào)用erase之前,記錄下一個元素的迭代器即可。
3.對于list來說,它使用了不連續(xù)分配的內(nèi)存,并且它的erase方法也會返回下一個有效的iterator,因此上面兩種正確的方法都可以使用
22、請你來說一下STL中迭代器的作用,有指針為何還要迭代器
Iterator(迭代器)模式又稱Cursor(游標(biāo))模式,用于提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內(nèi)部表示。
迭代器不是指針,是類模板,表現(xiàn)的像指針。他只是模擬了指針的一些功能,通過重載了指針的一些操作符,->、*、++、–等。
迭代器返回的是對象引用而不是對象的值,所以cout只能輸出迭代器使用*取值后的值而不能直接輸出其自身。
23、請你來說一下C++中struct和class的區(qū)別
這我倒是沒有關(guān)注過。
class可以定義模板類形參,比如template
結(jié)構(gòu)體(sturct)是一種值類型,而類(class)是引用類型。區(qū)別在于復(fù)制方式,值類型的數(shù)據(jù)是值賦值,引用類型的數(shù)據(jù)是引用復(fù)制。
結(jié)構(gòu)體使用棧存儲(Stack Allocation),而類使用堆存儲(Heap Allocation)。
棧的空間相對較小.但是存儲在棧中的數(shù)據(jù)訪問效率相對較高;堆的空間相對較大.但是存儲在堆中的數(shù)據(jù)的訪問效率相對較低
結(jié)構(gòu)體使用完之后就自動解除內(nèi)存分配,類實例有垃圾回收機(jī)制來保證內(nèi)存的回收處理 。
如何選擇結(jié)構(gòu)體還是類
1. 堆棧的空間有限,對于大量的邏輯的對象,創(chuàng)建類要比創(chuàng)建結(jié)構(gòu)好一些
2. 結(jié)構(gòu)體表示如點、矩形和顏色這樣的輕量對象。
3. 在表現(xiàn)抽象和多級別的對象層次時,類是最好的選擇,因為結(jié)構(gòu)體不支持繼承
4. 大多數(shù)情況下該類型只是一些數(shù)據(jù)時,結(jié)構(gòu)體時最佳的選擇
C 語言 C++
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。