C/C++ Tips (2)

1、C++裏的鑽石結構

      class A { };
      class B : virtual public A  { };
      class C : virtual public A { };
      class D : public B, public C { };

2、long和float都是用四個字節表示

3、關鍵字volatile的作用

        一個定義爲volatile的變量是說這變量可能會被意想不到的改變,這樣,編譯器就不會去假設這個變量的值了。精確的說就是,優化器在用到這個變量時必須每次都小心的重新讀取這個變量的值,而不是保存在寄存器裏的備份。

4、抽象類和接口的區別

        抽象類是特殊的類,只是不能被實例化(將定義了純虛函數的類稱爲抽象類);除此之外,抽象類具有類的其它特性;重要的是抽象類可以包含抽象類和抽象方法,這是普通類所不能的,但同時也可以包含普通的方法。抽象方法只能聲明於抽象類中,且不包含任何實現,派生類必須覆蓋它們。另外,抽象類可以派生自一個抽象類,可以覆蓋基類的抽象方法也可以不覆蓋,如果不覆蓋,則其派生類必須覆蓋它們。雖然不能定義抽象類的實例,但是可以定義它的指針,這正是抽象類實現接口的重點所在。

       接口是一個概念,它在C++中用抽象類實現,在C#和Java中用interface來實現。

       接口是引用類型的,類似於類,和抽象類的相似之處有三點。

               1)不能實例化

               2)包含未實現的方法和聲明

               3)派生類必須實現未實現的方法,抽象類是抽象方法,接口則是所有成員(不僅是方法,包括其它成員)

        另外,接口有如下特性:

        接口除了可以包含方法之外,還可以包含屬性、索引器、事件,而這些成員都被定義爲公有的。除此之外,不能包含其它的任何成員,例如:常量、域、構造函數、析構函數,靜態成員。

5、sizeof和strlen的區別

       sizeof是一種單目運算符,而strlen是一個函數。

       sizeof的操作數可以是數據類型、函數、變量、表達式

       strlen的應用則不像sizeof那麼廣泛,參數必須是char *型的指針

6、什麼是野指針,什麼情況下會產生野指針,如何避免?

       野指針是指向不可用內存區域的指針。通常對野指針進行操作的話,會產生不可預知的錯誤。

       野指針的產生有三種情況:

                 1)指針變量未被初始化

                 2)動態內存中指針被free或delete釋放後沒有被置爲null

                 3)指針操作超越了變量的作用範圍

      避免:我們需要將指針初始化爲NULL,用完後也爲其賦值NULL

                  拷貝構造時防止淺拷貝

7、面向對象的三個要素五個原則

     三要素:繼承封裝多態

         封裝:將抽象得到的數據和方法相結合,形成一個有機整體,使用者不必瞭解具體的實現細節,而只要通過外部接口,一特定的訪問權限來使用類的成員

         繼承:繼承可以使子類具有父類的各種屬性和方法,而不需要編寫相同的代碼

         多態:不同的對象調用相同的函數會產生不同的效果,允許將子類類型的指針賦給父類類型的指針

    五元則:單一職責原則

                         應該有且僅有一個原因引起類的變更 

                   開放封閉原則

                         對擴展開放,對修改封閉

                   里氏替換原則

                        子類可以擴展父類的功能,但不能改變父類的功能

                   依賴倒置原則

                        對抽象進行編程,不要對實現進行編程,這樣就降低了業務與實現模塊間的耦合

                   接口隔離原則 

                       使用多個專門的接口總比使用一個單一的接口好

8、與類相關的sizeof操作

定義一個 空的類,沒有任何的成員變量和成員函數,對該類型求sieof,得到的結果是多少?

答案是1,空類型的實例中不包含任何信息,本來求sizeof應該是0,但是當我們聲明該類型的實例的時候,它必須在內存中佔有一定的空間,否則無法使用這些實例。至於佔用多少內存,由編譯器決定。Visual Studio中每個空類型的實例佔用1字節的空間。

如果在該類型中添加一個構造函數和析構函數,再對該類型求sizeof,得到的結果又是多少?

和前面一樣,還是1。調用構造函數和析構函數只需要知道函數的地址即可,而這些函數的地址只與類型相關,而與類型的實例無關,編譯器也不會因爲這兩個函數而在實例內添加額外的信息。

那如果把析構函數標記爲 虛函數呢?

C++的編譯器一旦發現一個類型中有虛擬函數,就會爲該類型生成虛函數表,並在該類型的每一個實例中添加一個指向虛函數表的指針。在32位機器上,一個指針佔4個字節的空間。

9、不允許複製構造函數傳值

如果允許複製構造函數傳值,就會在複製構造函數內調用複製構造函數,就會形成無休止的遞歸調用從而導致棧溢出






          


   

   


發佈了40 篇原創文章 · 獲贊 4 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章