做自媒體發(fā)視頻用哪些網(wǎng)站百度域名查詢官網(wǎng)
目錄
1、關(guān)鍵字new:
1、用法:
2、理解:
3、與malloc的相同與不同:
1、相同:
2、不同:
2、模版初階:
1、函數(shù)模版:
1、概念:
2、關(guān)鍵字:template:
3、模版原理:
4、函數(shù)模版的實例化:
1、隱式實例化:
2、顯式實例化:
2、類模版:
1、定義格式:
2、類模版的實例化:
1、關(guān)鍵字new:
new是相對于C語言的malloc一個新的內(nèi)存管理方式,通過new和delete配套使用來進行動態(tài)內(nèi)存管理。
1、用法:
類型*? 名字 = new 類型;
例如:
int* ptr1 = new int;
這就是動態(tài)申請了一個int類型空間。
2、理解:
1、new()
這樣在()里面可以進行初始化,例如:
int* ptr2?= new int(10);這就是動態(tài)申請一個int類型的空間并初始化為10
2、new[n]
這樣就是分配這種類型的n個大小的內(nèi)存空間,并用默認構(gòu)造函數(shù)來初始化這些變量;
例如:
int* ptr6 = new int[10];這樣就是動態(tài)申請10個int類型的空間。
3、與malloc的相同與不同:
1、相同:
都是從對上申請的空間,并且都需要手動釋放。
2、不同:
其余的還有:
1、malloc和free是函數(shù),new和delete是操作符
2、malloc申請的空間不會初始化,new可以初始化(調(diào)用構(gòu)造函數(shù))
3、malloc申請空間時,需要手動計算空間大小并傳遞,new只需在其后跟上空間的類型即可, 如果是多個對象,[]中指定對象個數(shù)即可
4、malloc的返回值為void*, 在使用時必須強轉(zhuǎn),new不需要,因為new后跟的是空間的類型
5、malloc申請空間失敗時,返回的是NULL,因此使用時必須判空,new不需要,但是new需要捕獲異常
6、new/delete和malloc/free最大區(qū)別是 new/delete對于【自定義類型】除了開空間還會調(diào)用構(gòu)造函數(shù)初始化和析構(gòu)函數(shù)清理,但是二者對于內(nèi)置類型幾乎是一樣的。
class A
{
public:A(int a = 0): _a(a){cout << "A()" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};
int main()
{A* p1 = (A*)malloc(sizeof(A));A* p2 = new A(1);free(p1);delete p2;return 0;
}
調(diào)用構(gòu)造函數(shù)就可以對自定義類型進行初始化了,比如在鏈表那里,可以不用newnode了
2、模版初階:
引入:
在C語言中交換函數(shù)Swap存在“寫死”,但是一會兒要交換int類型,一會兒要交換double類型,那么就要我們寫很多不同種類的函數(shù),就很繁瑣,在C++中就引入了模版的概念,這樣可以大大減少代碼的重復度。
1、函數(shù)模版:
1、概念:
函數(shù)模板代表了一個函數(shù)家族(比如Swap函數(shù),可交換int double 等等),該函數(shù)模板與類型無關(guān),在使用時被參數(shù)化,根據(jù)實參類型產(chǎn)生函數(shù)的特定類型版本。
2、關(guān)鍵字:template:
模版格式:
template<typename T1,typename T2,......,typename Tn>
void 函數(shù)名(T& 形參名1,......,T& 形參名n)//注意權(quán)限情況加const
以下是示例代碼:
template<typename T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}
int main()
{int a = 1;int b = 2;Swap(a, b);cout << "a = " << a << endl << "b = " << b << endl;return 0;
}
3、模版原理:
雖然我們只寫了一個模版函數(shù),但是實際上調(diào)用是因為編譯器幫我們通過函數(shù)模版實現(xiàn)了不同的函數(shù),再調(diào)用它們來達到不同類型函數(shù)的調(diào)用。
4、函數(shù)模版的實例化:
函數(shù)模板的實例化:用不同類型的參數(shù)使用函數(shù)模板。
1、隱式實例化:
讓編譯器根據(jù)實參推演模板參數(shù)的實際類型叫做隱式實例化。
2、顯式實例化:
在函數(shù)名后的<>中指定模板參數(shù)的實際類型。
template<typename T>
T Add(const T& x,const T& y)
{return x + y;
}int main()
{int a = 10;double b = 20.10;cout << Add(a, b) << endl;return 0;
}
上述代碼中有個問題:就是a和b是不同類型的,但是在函數(shù)中又必須是同一種類型的,這樣的話就可以用顯式實例化或者在Add(a,b)中進行轉(zhuǎn)換。
1、在Add(a,b)中轉(zhuǎn)化就是轉(zhuǎn)化為:Add((double)a,b)或者Add(a,(int)b)
2、更好的一種方法就是用顯式實例化:
改為:Add<int>(a,b)或者Add<double>(a,b)
但是實際上不會這么用,在后面list等等數(shù)據(jù)結(jié)構(gòu)中會用到。
2、類模版:
1、定義格式:
template<class T1, class T2, ..., class Tn>
class 類模板名
{
?// 類內(nèi)成員定義
};
2、類模版的實例化:
類模板實例化與函數(shù)模板實例化不同,類模板實例化需要在類模板名字后跟<>,然后將實例化的類型放在<>中即可,類模板的名字不是真正的類,就是個名字,而實例化的結(jié)果才是真正的類。
比如我寫了一個棧模版
template<class T>
class Stack
{
public:Stack(size_t capacity = 3);void Push(const T& data);// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:T* _array;int _capacity;int _size;
};
那么棧的類名:Stack
棧的類型:Stack<T>
這里是將聲明與定義分離了,在函數(shù)外面進行定義就需要加上模版的聲明和類域的劃分
template<class T>
Stack<T>::Stack(size_t capacity)
{_array = new T[capacity];_capacity = capacity;_size = 0;
}template<class T>
void Stack<T>::Push(const T& data)
{_array[_size] = data;_size++;
}