灵活而奇特的C++语言特性——typedef & aliases

       学习了博主的《漫谈继承技术》系列博文之后,相信大家都有所收获吧!这次博主将和大家一起探讨 《灵活而奇特的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;

 

//使用typedefint指针取别名

typedef int*IntPtr;

//使用typedefstring矢量取别名

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;

 

//使用usingint指针取别名

using IntPtr= int*;

//使用usingstring矢量取别名

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++语言特性相关的知识和一些特性的理解和掌握。当然,如果你想了解关于继承方面的技术,请关注博主《漫谈继承技术》系列博文。



发布了81 篇原创文章 · 获赞 18 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章