C++問題總結(更新中)

問題1:函數返回數組

函數體內部創建的變量都是局部變量,當函數運行結束的時候,都會拋棄,也就是說你只返回了一個temp指針,這個指針確實是你想要的,這沒有問題,但是它指向的內容在函數結束也就是return的那一刻之後就已經物是人非了。所以你用這個這個指針去訪問的內容也不是你想要的內容了。
解決方法:動態內存分配,就是new和delete的配合使用。在函數裏用new關鍵字創建一個數組,這樣這塊地址對應的內容就屬於你管理了,再也不會在函數結束的時候被回收了,你也就可以通過返回的指針來訪問數組了,最後再delete一下。

問題2:sort()方法的使用

c++標準庫裏的排序函數的使用方法

I)Sort函數包含在頭文件爲#include <algorithm>的c++標準庫中,調用標準庫裏的排序方法可以不必知道其內部是如何實現的,只要出現我們想要的結果即可!
II)Sort函數有三個參數:
(1)第一個是要排序的數組的起始地址。
(2)第二個是結束的地址(最後一位要排序的地址)
(3)第三個參數是排序的方法,可以是從大到小也可是從小到大,還可以不寫第三個參數,此時默認的排序方法是從小到大排序。
Sort函數使用模板:
Sort(start,end,compare)
eg:

bool compare(int a,int b)
{
    return a>b;
}

問題3:關於free

free之後的指針仍然指向原來的堆地址,即仍然可以繼續使用,但很危險。因爲操作系統已經認爲這塊內存可以使用,它會毫不考慮的將他分配給其他程序,於是你下次不小心使用到該指針(野指針)時,如果操作系統及時制止了這種行爲,報錯(非法操作),然後將你的程序殺掉,給你很容易改正錯誤的機會,這還算比較好的結果!如果操作系統沒有制止這種行爲,那麼產生的後果可就說不準了,說不定整個操作系統會崩潰,那麼你再來改正這個錯誤,就不容易發現,所以會出現未定義的錯誤。最好free了以後再置空,即令指針 = NULL;,表示本程序已經放棄再使用該指針。 delete 會調動析構函數,free不會。

問題4:野指針

野指針指向一個已刪除的對象或未申請訪問受限內存區域的指針。與空指針不同,野指針無法通過簡單地判斷是否爲 NULL避免,而只能通過養成良好的編程習慣來盡力減少。對野指針進行操作很容易造成程序錯誤。需對指針進行初始化。

問題5:構造(析構)函數執行順序

當派生類中不含對象成員時:
在創建派生類對象時,構造函數的執行順序是:基類的構造函數 → 派生類的構造函數;
在撤消派生類對象時,析構函數的執行順序是:派生類的析構函數 → 基類的析構函數。

當派生類中含有對象成員時:
在定義派生類對象時,構造函數的執行順序:基類的構造函數 → 對象成員的構造函數 → 派生類的構造函數;
在撤消派生類對象時,析構函數的執行順序:派生類的析構函數 → 對象成員的析構函數 → 基類的析構函數。
對象成員是包含在類中的對象

問題6:新型強制類型轉換

static_castdynamic_castconst_castreinterpret_cast
https://www.cnblogs.com/chenyangchun/p/6795923.html

問題7:關於this指針

如果還有一個變量myclass mz,mz的this就是指向mz的指針。 這樣就很容易理解this 的類型應該是myclass *,而對其的解引用*this就應該是一個myclass類型的變量。

  1. this指針的用處:
    一個對象的this指針並不是對象本身的一部分,不會影響sizeof(對象)的結果。
    this作用域是在類內部,當在類的非靜態成員函數中訪問類的非靜態成員的時候,編譯器會自動將對象本身的地址作爲一個隱含參數傳遞給函數。也就是說,即使你沒有寫上this指針,編譯器在編譯的時候也是加上this的,它作爲非靜態成員函數的隱含形參,對各成員的訪問均通過this進行。例如,調用date.SetMonth(9) <===> SetMonth(&date, 9),this幫助完成了這一轉換 .
    在成員函數內部,我們可以直接使用調用該函數的對象的成員,而無需通過成員訪問運算符來做到這一點,因爲this所指的正是這個對象。任何對類成員的直接訪問都被看成this的隱式使用。
    this的目的總是指向這個對象,所以this是一個常量指針,我們不允許改變this中保存的地址
  2. this指針的使用:
    一種情況就是,在類的非靜態成員函數中返回類對象本身的時候,直接使用 return *this;另外一種情況是當參數與成員變量名相同時,如this->n = n (不能寫成n = n)。
  3. this指針程序示例:
    this指針是存在於類的成員函數中,指向被調用函數所在的類實例的地址。

問題8:文件模式

  1. 文件模式常量

常量 含義
ios_base::in 打開文件,以便讀取
ios_base::out 打開文件,以便寫入
ios_base::ate 打開文件,並移到文件尾
ios_base::app 追加到文件尾
ios_base::trunc 如果文件存在,則截短文件
ios_base::binary 二進制文件
eg:

ofstream ofs("C:\\Users\\03\\Desktop\\1.txt",ofstream::app);//追加到文件的後面,不會覆蓋原來內容。

問題9:深拷貝淺拷貝

https://blog.csdn.net/qiqi_77_/article/details/79400900
https://blog.csdn.net/caoshangpa/article/details/79226270

問題10:移動構造函數

https://blog.csdn.net/sinat_25394043/article/details/78728504
複製構造是這樣的:
在對象被複制後臨時對象和複製構造的對象各自佔有不同的同樣大小的堆內存,就是一個副本。
移動構造是這樣的:
就是讓這個臨時對象它原本控制的內存的空間轉移給構造出來的對象,這樣就相當於把它移動過去了。
類似文件的“複製” 和“移動”操作。
複製構造和移動構造的差別:
這種情況下,我們覺得這個臨時對象完成了複製構造後,就不需要它了,我們就沒有必要去首先產生一個副本,然後析構這個臨時對象,這樣費兩遍事,又佔用內存空間,所幸將臨時對象它的原本的資源直接轉給構造的對象即可了。
當臨時對象在被複制後,就不再被利用了。我們完全可以把臨時對象的資源直接移動,這樣就避免了多餘的複製構造。
什麼時候該觸發移動構造呢?
如果臨時對象即將消亡,並且它裏面的資源是需要被再利用的,這個時候我們就可以觸發移動構造。

問題11:右值引用

https://www.cnblogs.com/qicosmos/p/4283455.html
在C++11中所有的值必屬於左值將亡值純右值三者之一。比如,非引用返回的臨時變量、運算表達式產生的臨時變量、原始字面量和lambda表達式等都是純右值。而將亡值是C++11新增的、與右值引用相關的表達式,比如,將要被移動的對象、T&&函數返回值、std::move返回值和轉換爲T&&的類型的轉換函數的返回值等
右值是匿名變量,我們也只能通過引用的方式來獲取右值.
右值引用接管資源,不用重新創建臨時資源再拷貝,提高了程序的執行效率。

問題12:std::move()

參見源碼:
原理:
https://www.cnblogs.com/zoneofmine/p/7440577.html

 template <typename T>
    typename remove_reference<T>::type&& move(T&& t)
    {
        return static_cast<typename remove_reference<T>::type&&>(t);
    }

問題13:迭代器範圍(左閉右開)

c++的迭代器範圍爲左閉右開區間,泛型算法以及一些接受迭代器範圍的構造函數都是採用的左閉右開區間。
eg:

string s1("hello");
string s2(s1.begin(),s1.begin()+4);  //此時s2 = "hell"而非”hello“

問題14:union 內存對齊

union的sizeof值確定方法:
1.必須放得下union裏的任何一個元素或元素集合(如數組)
2.必須是union裏最寬基本類型的sizeof值的整數倍。

 union u{
 		A a;
 		B b[3];
 		C c;
 }

sizeof(A)=2;sizeof(B)=3;sizeof(C)=5;
則sizeof(u) = 10
總結:
以最長的(b[3])爲基準,對齊最大的類型( C )
https://blog.csdn.net/musiccow/article/details/5817285

問題15:對象所佔內存

1.非靜態成員變量總和
2.數據對齊處理
3.支持虛函數所帶來的負擔(虛函數表指針)
空類型對象會開闢內存,所以sizeof不爲0.

問題16:字符串與字符數組詳解

https://www.cnblogs.com/skullboyer/p/7807543.html

問題17:內存分配

一個由C/C++編譯的程序佔用的內存分爲以下幾個部分:
1、棧區(stack)— 由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS(操作系統)回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。
3、全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。程序結束後由系統釋放。
4、文字常量區 —常量字符串就是放在這裏的。程序結束後由系統釋放。
5、程序代碼區—存放函數體的二進制代碼。

問題18:編譯鏈接

在這裏插入圖片描述

問題19:編譯過程

在這裏插入圖片描述

問題20:引用型成員

凡是有引用類型的成員變量的類,不能有缺省構造函數。默認構造函數沒有對引用成員提供默認的初始化機制,也因此造成引用未初始化的編譯錯誤。
構造函數的形參必須爲引用類型
https://www.cnblogs.com/tangmiao/p/7777008.html

問題21:printf()無輸出

printf("s_addr:%d",(servaddr.sin_addr.s_addr));

原因: printf()是帶緩衝的,此時內容在緩衝區沒有輸出到標準輸出。
解決方法: 加入“\n”將緩衝區數據刷到輸出設備。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章