[C++] 处理类型

类型别名

类型别名是一个名字,它是某种类型的同义词。

定义类型别名可以使用关键字typedef

typedef double wages;
// wages是double的同义词
typedef wages base, *p;
// base是double的同义词,p是double*的同义词

定义类型别名也可以使用别名声明

using SI = Sales_item;
// SI是Sales_item的同义词

指针、常量和类型别名

typedef char *pstring;
const pstring cstr = 0;
// cstr是指向char的常量指针
const pstring *ps;
// ps是一个指针,它的对象是指向char的常量指针。

声明语句中用到pstring时,其基本数据类型是指针,此时const pstring表示常量指针。

auto类型说明符

用它就能让编译器替我们取分析表达式所属的类型。是通过初始值来推算变量的类型,则要求auto必须有初始值

如果使用auto在一条语句中声明多个变量,则该语句中所有变量的初始基本类型都必须一样

auto i = 0, *p = &i;
// 正确
auto sz = 0, pi = 3.14;
// 错误

使用引用其实是使用引用的对象,特别是当引用被用作初始值时,真正参与初始化的其实是引用对象的值

auto一般会忽略顶层const,同时底层const则会保留下来。

const int ci = i, &cr = ci;
auto b = ci;
// b ~ int
auto c = cr;
// c ~ int
auto d = &i;
// d ~ int* 整数的地址就是指向整数的指针
auto e = &ci;
// e ~ const int*
// e是一个指向整数常量的指针(对常量对象取地址是一种底层const)

如果希望auto类型是一个顶层const,则

const auto f = ci;
// ci ~ int, f ~ const int

&和*属于声明符,而非基本数据类型。在使用auto时需要特别注意。

int i = 0;
const int ci = i, &cr = ci;

auto k = ci, &l = i;
// k ~ int
// l ~ int&

auto &m = ci, *p = &ci;
// m ~ const int&
// p ~ const int*

// i ~ int
// &ci ~ const int.
// 练习2.35:判断下列定义推断出的类型是什么。
const int i = 42;
auto j = i;
// j ~ int
const auto &k = i;
// &k ~ const int&
auto *p = &i;
// *p ~ int*
const auto j2 = i, &k2 = i;
// j2 ~ const int
// &k2 ~ const int&

decltype

它的作用是选择并返回操作数的数据类型。编译器分析表达式并得到他的类型,却不实际计算表达式

decltype(f()) sum = x;
// sum的类型是函数f的返回类型

decltype处理顶层const和引用与auto不同。

decltype使用的表达式是一个变量,则返回该变量的类型(包括顶层const和引用在内)

const int ci = 0, &cj = ci;
decltype(ci) x = 0;
// x ~ const int
decltype(cj) y = x;
// y ~ const int &
decltype(cj) z;
// 错误,z为引用,必须初始化

decltype的结果可以是引用类型

int i = 42, *p = &i, &r = i;
decltype(r + 0) b;
// decltype(r) 的结果是引用类型,
// decltype(r + 0)的结果是int类型
decltype(*p) c;
// 错误,c是int&,必须初始化

如果表达式的内容是解引用操作,则decltype将得到引用类型。

decltype结果与表达式形式密切相关。

如果decltype的表达式是一个变量,不加括号结果是该变量的类型,加上括号编译器会把它当初表达式。

变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype会得到引用类型

decltype((i)) d;   
// 错误,d必须初始化,因为d ~ int&
decltype(i) e;
// 正确,e是一个未初始化的int 

decltype((var))永远是一个引用

decltype(var)只有当var是一个引用时才是引用

decltype与auto区别

1、如果使用引用类型,auto会识别为其所指对象的类型,decltype会识别为引用的类型

2、decltype(())双括号的差别,双括号永远是引用

预处理器

确保头文件多次包含仍能安全工作的常用技术是预处理器

当预处理器看到#include标记时会用指定的头文件的内容代替#include

头文件保护符

头文件保护符依赖于预处理变量,预处理办理有两种状态:已定义和未定义。

#define指令把一个名字设定为预处理变量,另外两个指令则分别检查某个指定的预处理变量是否已经定义:

#ifdef当且仅当变量已定义时为真。

#ifndef当且仅当变量未定义时为真,

一旦检查结果为真,则执行后续操作直到遇到#endif指令为止

Tips:

1、使用typedef定义类型别名

2、使用using定义类型别名

3、当我们不知道变量表达式的类型时,可以使用auto让编译器为我们决定表达式的类型

4、auto会自动忽略掉顶层const,而底层const会被保留。

5、auto定义的变量必须有初始值。

6、decltype:希望从表达式的类型推断出想要定义的变量的类型,该操作返回操作数的类型。

7、赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型,也就是说,如果i是int,则表达式i=x的类型是int&

原文地址:https://www.cnblogs.com/immjc/p/8023024.html