一、别名aliases
别名,好理解就是另外一个名字。其实说白了,有点类似于笔名、小名等,反正都是指的同一个事物。别名的用意在编程里非常简单,就是为了方便好记。举一个例子,一个变量从属于某个类,这个类又属于某个空间,这个空间
又属于另外一个空间,那好,这个名字如果被外部调用,可以想想得有多长。如果再有类似的空间名,恰好这个空间里又一个相同的名字的变量,可以想见,出错的概率增大多少。
在c++中,变量、类型、函数和模板都可以使用别名;类和名空间也可以使用别名。别名就是为了省略编写代码的量,减轻重复代码的录入,提高辨识度。
二、别名的方法
1、使用define
这个比较简单,形如:
#define aliases name
2、typedef
它和上面的似乎有点相反:
#typedef name aliases
3、using
using 标识符 属性(可选) = 类型标识 ;
template < 模板形参列表 >
using 标识符 属性(可选) = 类型标识 ;
4、直接定义
namespace 别名 = 命名空间名; (1)
namespace 别名 = ::命名空间名; (2)
namespace 别名 = 嵌套名::命名空间名; (3)
三、源码实例
1、变量类型别名
变量的别名可以使用宏定义#define 和 typedef来实现,也可以用c++11中的using来实现。变量别名一般用在固定的值,比如圆周率、常数等的有意义命名;其它项目中的相关变量引用重命名;过长变量或者容易混淆的变量的重命名
等。说的直白一些,只要愿意在代码中就可以对相关变量进行别名设置:
#define PI 3.14
typedef unsigned logn ulong
using myPtr = int *;
2、函数别名
函数别名也是类似于类型变量的别名,特别是在使用函数指针时:
typedef int (*FUNC)(int x,int y);
using FUNC = int (int x, int y);
3、模板别名
模板的别名有两种情况,一种是正常的模板别名,一种是特化情况下的别名:
//普通使用
template<class T>
struct Alloc { };
template<class T>
using Vec = vector<T, Alloc<T>>; // 类型标识为 vector<T, Alloc<T>>
Vec<int> v;
//特化
// 用于隐藏模板形参的别名模版
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
mystring<char> str;
//c++20
template <class T>
using A = decltype([] { }); // A<int> 与 A<char> 指代不同的闭包类型
4、名空间别名
名空间别名可以直接定义:
namespace fbz = foo::bar::baz;
下面看一个整体的例子,通过例程更容易理解:
#include <iostream>
#include <map>
#include <string>
#include <vector>
#define PI 3.14
typedef char Name[10];
Name _name;
using myvec = std::vector<int>;
template <typename T>
using iMap = std::map<int, T>;
//下面是函数类型的例子,函数指针的例程请自己对比分析
typedef int FUNC(int a, int b);
using FUNC0 = double(*)(double a, double b);
int Mul(int a, int b)
{
return a * b;
}
double Add(double a, double b)
{
return a * b;
}
namespace d {
namespace d0 {
namespace d1 {
int ddd = 36;
}
}
}
namespace d3 = d::d0::d1;
int main()
{
myvec vec(10);
for (int i = 0; i < 10; i++)
{
_name[i] = i;
vec[i] = i + 1;
}
iMap<std::string> kv;
kv[0] = "success";
std::cout << "key 0 value is:" << kv[0] << std::endl;
FUNC* myfunc = Mul;
int r = myfunc(2,3);
std::cout << "FUNC " << r << std::endl;
FUNC0 myfunc0 = Add;
float fr = myfunc0(PI,4.00);
std::cout << "FUNC0 " << fr << std::endl;
std::cout << "FUNC namespae " << myfunc(1, d3::ddd) << std::endl;
return 0;
}
运行结果为:
key 0 value is:success
FUNC 6
FUNC0 12.56
FUNC namespae 36
当然,上面的例子还是不太全面,比如typedef的用法就还有不少,举一反三,可以去更多的资料来查看,这里算是一个抛砖引玉的动作吧。
三、总结
好多技术点看起来非常简单,遇到也觉得没有什么。但是,如果想把它们全都总结出来,发现还真是挺费精神。如果有一些简单的知识点组合起来使用,可能会更让人感觉到明明认识,大概也知道什么意思,可是为什么从来没
见过用过呢?这就需要不断的跟进技术标准的迭代并不断的多看别人的代码。人在发展到一定阶段后,就会产生信息蚕茧,不愿意或者无意识的封闭在这个信息空间里。
要善于打开视野,不断开拓进取。睁眼看世界,认真写代码。