C++筆記 第五十五課 經典問題解析四---狄泰學院
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第五十五課 經典問題解析四
1.關於動態記憶體分配
new和malloc的區別是什麼?
delete和free的區別是什麼?
new關鍵字與malloc函式的區別
new關鍵字是C++的一部分
malloc是由C庫提供的函式
new以具體型別為單位進行記憶體分配
malloc以位元組為單位進行記憶體分配
new在申請記憶體空間時可進行初始化
malloc僅根據需要申請定量的記憶體空間
下面的程式碼輸出什麼?為什麼?
55-1 new和malloc的區別
#include <iostream> #include <string> #include <cstdlib> using namespace std; class Test { int* mp; public: Test() { cout << "Test::Test()" << endl; mp = new int(100); cout << *mp << endl; } ~Test() { delete mp; cout << "~Test::Test()" << endl; } }; int main() { Test* pn = new Test; Test* pm = (Test*)malloc(sizeof(Test)); delete pn; //free(pn); //malloc //delete pm; //new free(pm); return 0; } 執行結果 Test::Test() 100 ~Test::Test()
new和malloc的區別
new在所有C++編譯器中都被支援
malloc在某些系統開發中是不能呼叫–需要C庫支援
new能夠觸發建構函式的呼叫
malloc僅分配需要的記憶體空間
物件的建立只能使用new
malloc不適合面向物件開發
下面的程式碼輸出什麼?為什麼?—注意成對出現的語句
delete和free的區別
delete在所有C++編譯器中都被支援
free在某些系統開發中是不能呼叫
delete能夠觸發解構函式的呼叫
free僅歸還之前分配的記憶體空間
物件的銷燬只能使用delete
free不適合面向物件開發
2.關於虛擬函式
建構函式是夠可以成為虛擬函式?不可以
解構函式是夠可以成為虛擬函式?可以
建構函式不可能成為虛擬函式
在建構函式執行結束後,虛擬函式表指標才會被正確的初始化
解構函式可以成為虛擬函式
建議在設計類使將解構函式宣告為虛擬函式
55-2 構造,析構,虛擬函式
#include <iostream> #include <string> using namespace std; class Base { public: Base() { cout << "Base()" << endl; func(); } virtual void func() { cout << "Base::func()" << endl; } virtual ~Base() { func(); cout << "~Base()" << endl; } }; class Derived : public Base { public: Derived() { cout << "Derived()" << endl; func(); } virtual void func() { cout << "Derived::func()" << endl; } ~Derived() { func(); cout << "~Derived()" << endl; } }; int main() { Base* p = new Derived(); // ... delete p; return 0; } 執行結果 Base() Base::func() Derived() Derived::func() Derived::func() ~Derived() Base::func() ~Base()
建構函式中是夠可以發生多型?不可能
解構函式中是夠可以發生多型?不可能
建構函式中不可能發生多型行為
在建構函式執行時,虛擬函式表指標未被正確初始化
解構函式中不可能發生多型行為
在解構函式執行時,虛擬函式表指標已經被銷燬
建構函式和解構函式中不能發生多型行為,只調用當前類中定義的函式版本!!
3.關於繼承中的強制型別轉換
繼承中如何正確的使用強制型別轉換?
dynamic_cast是與繼承相關的型別轉換關鍵字
dynamic_cast要求相關的類中必須有虛擬函式
用於有直接或者間接繼承關係的指標(引用)之間
指標:
轉換成功:得到目標型別的指標
轉換失敗:得到一個空指標
引用:
轉換成功:得到目標型別的引用
轉換失敗:得到一個異常操作資訊
編譯器會檢查dynamic_cast的使用是否正確
型別轉換的結果只可能在執行階段才能得到
55-3 dynamic_cast
列印Cast error的原因:不能用子類的指標指向一個父類的物件
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base::Base()" << endl;
}
virtual ~Base()
{
cout << "Base::~Base()" << endl;
}
};
class Derived : public Base
{
};
int main()
{
Base* p = new Base;
Derived* pd = dynamic_cast<Derived*>(p);
if( pd != NULL )
{
cout << "pd = " << pd << endl;
}
else
{
cout << "Cast error!" << endl;
}
delete p;
return 0;
}
執行結果
Base::Base()
Cast error!
Base::~Base()
小結
new/delete會觸發建構函式或者解構函式的呼叫
建構函式不能成為虛擬函式
解構函式可以成為虛擬函式
建構函式和解構函式中無法產生多型行為
dynamic_cast是與繼承相關的專用轉換關鍵字