我們一定要堅信,在堅持中才能看到希望,而不是看到希望后才開始堅持
Q1:問請用簡單語句告訴我C++是什么?
C++是在C語言的基礎上開發的一種面向對象編程語言,應用廣泛。C++融合了3種不同的編程方式:C語言代表的過程性語言、C++在C語言基礎上添加的類代表的面向對象語言、C++模板支持的泛型編程。其編程領域眾廣,常用于系統開發、引擎開發等應用領域,是最受廣大程序員受用的最強大編程語言之一,支持類及繼承、封裝和多態等特性
Q2:C和C++的區別?
C++在C的基礎上增添類,C是一個結構化語言,它的重點在于算法和數據結構。C程序的設計首要考慮的是如何通過一個過程,對輸入(或環境條件)進行運算處理得到輸出(或實現過程(事務)控制)。而對于C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通過獲取對象的狀態信息得到輸出或實現過程(事務)控制。
Q3:什么是面向對象(OOP)?
面向對象是一種對現實世界理解和抽象的方法、思想,通過將需求要素等轉化為對象進行問題處理的思想。 用一張圖展示就是:
Q3:指針和引用的區別?
序 號 | 描述 | 指針 | 引用 |
---|---|---|---|
1 | 定義 | 是一個變量,存儲的是一個內存地址 | 變量的別名 |
2 | 初始化 | 可以為空值 | 不可以為空值,且必須初始化 |
3 | 多級 | 可以多級 | 只能一級 |
4 | 改變值 | 初始化后可以改變,即指向其他的存儲單元 | 初始化后不可以再改變 |
5 | sizeof | 得到的是指針本身的大小 | 所指向的變量的大小 |
6 | 內存分配 | 指針需要分配內存空間 | 引用不需要分配 |
7 | 解引用 | 指針需要解引用 | 引用無需解引用 |
注:解引用就可以理解為“解碼”的意思。假設ptr里面存放的是一個內存地址,那么 * ptr就是這個內存地址里面存放的數據。前面這個“* ”的解引用操作,就可以理解為對這個ptr進行解碼,解碼得到的數據就是* ptr,也就是我們常說的“這個內存地址里面存放的數據”或者“這個指針指向的數據”?!爸羔槨钡睦斫饽J教菀谆煜敖獯a”的理解模式更好記一點。
Q4:const在函數中可以作用在哪些地方,意義分別是啥?
const int num(int x);代表num函數的返回值是int類型的常量 int num(int x) const;代表的num函數不能隱形的修改參數x的值 int num(const int x);代表參數x是常量,不可以修改
Q5:new/delete 和 malloc/free 的區別?
相同點:都是申請內存和釋放內存 本質區別:malloc/free是C/C++ 語言的標準庫函數,new/delete是C++的運算符。 對于用戶自定義的對象而言,用malloc/free無法滿足動態管理對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由于malloc/free是庫函數不是運算符,不在編譯器的控制范圍之內,不能夠把執行構造函數和析構函數的任務強加給malloc/free,因此C++需要一個能完成動態內存分配和初始化工作的運算符new,以及一個能完成清理和釋放內存工作的運算符delete。 聯系:C++程序要經常調用C函數,而C程序只能調用malloc/free管理動態內存。因此兩者要共存。Q6:友元的作用?
友元分為友元類和友元函數。 特點:是一種定義在類外部的普通函數或者類,但他需要在類內部進行說明。為了和類的成員函數進行區分,在說明的前面加以 friend關鍵字。友元不是成員函數,但是他可以訪問類的私有成員。友元的作用是提高程序的運行效率,但是他破壞了程序的封裝性和隱藏性。使得非成員函數可以方位類的私有成員。
Q7:虛析構函數的作用?
一般情況下,類的析構函數里面都是釋放內存資源,而析構函數不被調用的話,就會發生內存泄漏。當然并不是把所有的析構函數都寫成虛析構函數,因為當類里面有虛函數的時候,編譯器會給類添加一個虛函數表,里面用來存放虛函數的指針,從而增加的類的空間。所有只有當類為基類時,才將析構函數寫成虛析構函數。
Q8:虛繼承的作用?
基本原則是在內存中只有基類成員的一份拷貝。這樣通過把基類繼承聲明為虛擬的,就只能繼承基類的一份拷貝,從而消除歧義。 class A : virtual class B{ };
Q9:宏定義的特點和實現,內聯函數取代他的意義
宏定義在形式和使用上像一個函數,但他使用預處理器實現,沒有了參數壓棧、代碼生成等一系列操作。因此效率很高。 雖然效率高,但是是在預處理器中實現的,所以不能進行參數的有效檢測,也就不能享受C++編譯器嚴格類型檢查的好處,另外返回值也不能強制轉換成可轉換的合適的類型。 C++中引入了類和類的訪問控制,這樣如果一個表達式涉及到類的保護成員或者私有成員,就不能用宏定義來實現。 正因為如此,引入了內聯函數。內聯函數的代碼被放入到符號表中,在使用時直接進行替換,沒有了展開的開銷,效率也很高。 類的內聯函數也是一個真正的函數,編譯器在調用一個內聯函數時,會首先檢查他的參數類型,保證調用正確。消除了隱患和局限性。 內斂函數可以作為某個類的成員函數,當然就可以在其中使用所在類的保護成員及私有成員。 內斂函數一般只會用在函數內容比較簡單的時候,這樣,函數的代碼會在任何調用他的地方展開。內聯函數最重要的使用地方是:類的存取函數。Q10:Qt的垃圾回收機制
Qt是以對象樹的形式來實現對垃圾的收集。所有繼承自QOBJECT類的類,在new的時候就指定了父親,那么在父親delete的時候,他也被清理delete。
Q11:Qt信號槽的簡單實現原理?
整個原理是比較復雜的,這里只做簡單介紹,有興趣童鞋可搜索細節
在預編譯時,保存信號函數和槽函數的索引為字符串,通過宏定義來實現。 建立鏈接,就是講信號索引字符串和槽函數索引字符串保存在map中,建立Key-Value的關系 當信號函數觸發后,先去找字符串索引,然后再去找map值,然后找到槽函數索引字符串,然后再在分支語句中找到槽函數。至此實現,哈哈,這些可以忽悠一下了,不過細節還需準備為好。Q12:線程和進程的區別?
進程是程序的一次執行;線程是進程的執行單元。 進程間是獨立的,這表現在內存空間、上下環境。線程運行在進程中。 一般來講,進程無法突破進程邊界存取其他進程內的存儲空間;而同一進程所產生的線程共享內存空間。 同一進程中的兩段代碼不能同時進行;除非引入多線程。新聞熱點
疑難解答
圖片精選