學習了博主的《漫談繼承技術》系列博文之後,相信大家都有所收穫吧!這次博主將和大家一起探討 《靈活而奇特的C++語言特性》 ,主要包括引用、常量(const)、常量表達式(constexpr)、靜態(static)、外部(expert)、類型定義(typedef)、類型別名(aliases)、類型轉換、作用域解析、統一初始化、顯示轉換運算符、特性(attribute)、用戶自定義文本、頭文件、可變長度參數列表和預處理器宏。儘管這個知識清單顯得有點凌亂,但是這些話題都是博主經過精心挑選,是容易混淆的語言特性。本篇我們來學習一下typedef和類型別名(aliases)的概念以及使用場景,增進大家對《靈活而奇特的C++語言特性》的理解。
typedef
typedef爲已有的類型聲明提供一個新的名稱。可以將typedef看成已有類型聲明的同義詞,typedef不會創建新的類型。typedef的最常見用法是當實際類型的聲明過於複雜時,提供易於管理的名稱,這一情形通常出現在函數指針和模板中。當然,typedef還可以包括作用域限定符。下面咱們來舉個栗子吧。
#include <iostream>
#include <string>
#include <vector>
using namespacestd;
//使用typedef給int指針取別名
typedef int*IntPtr;
//使用typedef給string矢量取別名
typedef std::vector<std::string> StringVector;
//使用typedef給函數指針類型取別名
typedef int(*FuncPtr)(std::initializer_list<int>list);
//初始化列表簡化了參數數量可變函數的編寫
int Sum(initializer_list<int>list)
{
intresult = 0;
//用for each累加列表中的值
foreach(constint&var in list)
{
result+= var;
}
returnresult;
}
void print(StringVector&vStr)
{
cout<< "vStr = {";
for(constauto&var : vStr)
{
cout<< var << ", ";
}
cout<< "}" << endl;
}
int main(intargc,char**argv)
{
//使用類型別名定義int指針變量
IntPtr nPtr = new int(10);
cout<< "*nPtr: "<< *nPtr << endl;
//使用類型別名定義string矢量
StringVector vStr;
//調整數組大小爲2,保證能保存兩個數據元素
vStr.reserve(2);
vStr.push_back("typedef");
vStr.push_back("std::vector<std::string>");
//調用函數輸出數組中所有元素
print(vStr);
//使用類型別名定義函數指針變量
FuncPtr fPtr = Sum;
//通過函數指針變量調用函數
autoresult = fPtr({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
cout<< "result:" << result << endl;
//釋放堆上空間
deletenPtr;
//避免野指針
nPtr = nullptr;
return0;
}
程序運行結果:
可能有的人還是覺typedef在定義函數指針時,有點麻煩,不怎麼好理解。沒有關係,我們還有跟簡便的方法來實現取別名的目的,而且還很容易理解。那究竟是什麼呢?就是我們之前在《漫談繼承技術》系列博文中講到的using。如果忘記了,那就把這篇博文學習完後回去再複習回顧一下!下面我們一起來探討一下using的高級用法。我們可以把上例轉換爲以下實例。
#include <iostream>
#include <string>
#include <vector>
using namespacestd;
//使用using給int指針取別名
using IntPtr= int*;
//使用using給string矢量取別名
using StringVector= std::vector<std::string>;
//使用using給函數指針類型取別名
using FuncPtr= int(*)(std::initializer_list<int>list);
//初始化列表簡化了參數數量可變函數的編寫
int Sum(initializer_list<int>list)
{
intresult = 0;
//用for each累加列表中的值
foreach(constint&var in list)
{
result += var;
}
returnresult;
}
void print(StringVector&vStr)
{
cout<< "vStr = {";
for(constauto&var : vStr)
{
cout<< var << ", ";
}
cout<< "}" << endl;
}
int main(intargc,char**argv)
{
//使用類型別名定義int指針變量
IntPtr nPtr = new int(10);
cout<< "*nPtr: "<< *nPtr << endl;
//使用類型別名定義string矢量
StringVector vStr;
//調整數組大小爲2,保證能保存兩個數據元素
vStr.reserve(2);
vStr.push_back("typedef");
vStr.push_back("std::vector<std::string>");
//調用函數輸出數組中所有元素
print(vStr);
//使用類型別名定義函數指針變量
FuncPtr fPtr = Sum;
//通過函數指針變量調用函數
autoresult = fPtr({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
cout<< "result:" << result << endl;
//釋放堆上空間
deletenPtr;
//避免野指針
nPtr = nullptr;
return0;
}
程序運行結果:
通過上例的學習,我們發現:當typedef變得複雜時(例如前面列舉的typedef用於函數指針和模板的情況),類型別名特性特別有用。關於typedef和別名(using)我們就探討到這裏了。當然,using的用法不僅僅在於別名,還可以在繼承技術方面大顯身手,如果想了解using的更多用法,請關注博主《漫談繼承技術》系列博文,我們將會在那裏繼續探討using的用法。
如果想了解更多關於C++語言特性相關的知識,請關注博主《靈活而奇特的C++語言特性》系列博文,相信你能夠在那裏尋找到更多有助你快速成長和加深你對C++語言特性相關的知識和一些特性的理解和掌握。當然,如果你想了解關於繼承方面的技術,請關注博主《漫談繼承技術》系列博文。