C++ Primer Notes(5): 复合类型

A compound type is a type that is defined in terms of another type. C++ has several compound types, two of which—references and pointers—we’ll cover in this chapter.

所谓 compound types(复合类型),是说基于其他类型定义出的类型。最典型的复合类型有两个:

  • 指针类型
  • 引用类型

回顾2.2节提到的「简单声明」,当时说 Type name[=value] 的形式,其实过于简化了。一个完整的声明,是一个 base type 打头, 后面跟着一个 declarator。 C++ Primer 书上没介绍 declarator,可以在 cppreference 上查到
https://en.cppreference.com/w/cpp/language/declarations
在这里插入图片描述
在这里插入图片描述

引用类型

A reference defines an alternative name for an object. A reference type “refers to” another type.

  • 引用,其实是给对象起了一个新名字
    • 本质是 “bind” 到一个已经存在的 object 上
    • 这意味着,定义引用变量时必须初始化,并且不能重新绑定到其他对象
  • 引用类型,引用了另一个类型

在这里插入图片描述

指针类型

指针类型在定义变量时可以不初始化。

和其他内置类型类似,在 block scope 里定义的指针如果没初始化,值是undefined。应当避免这种情况。

#include <iostream>

int main()
{
    int* p; // 这里没有初始化。很遗憾,gcc/clang没有编译选项来给出警告或error。

    std::cout << p << std::endl;

    return 0;
}

上述代码在 AppleClang 下并不能发现编译错误或警告。
在 GCC 11.4 下则可以看到警告:
在这里插入图片描述

指针的值,是一个地址。这个地址,有4种情况:
在这里插入图片描述
其中只有第一种情况(指向对象)时,访问指针的值是意义的、有定义的; 其他三种情况下,访问指针的值都是undefined。

初始化所有指针
不得不说这是C++的坑。没有初始化的指针,编译器并不能检测出来;但是呢,没有初始化的指针,容易引发各种运行时错误。
在这里插入图片描述
void*指针和其他指针的区别
在这里插入图片描述
void* 可以存储任意类型变量的地址, int* 这样的具体类型的指针,则是有类型并且不能转到其他类型的。比如 long* lp = &i 就不行,因为 &iint* 类型而不是 long* 类型。

再谈复合类型声明

int* p;

其中 int 是 base_type。 也就是说 base_type 并不是 int* 而是 int.
*type modifier,修改了 p 的类型。

正因如此,

int* p1, p2;

声明了 p1 为 int* 类型, p2 为 int 类型。

推荐的两种写法:

  • 如果是每行只定义一个复合类型变量,那么 type modifier 和 base_type 挨着
int* p1;
int* p2;
  • 如果是每行定义多个复合类型变量, 那么 type modifier 和每个变量挨着
int *p1, *p2;

Referenecs to pointers 指针的引用类型

int main()
{
    int i = 42;
    int* p;
    int* &r = p;
    r = &i;

    int a = 3;
    int& b = a;
    int c = 5;
    b = c;

    return 0;
}

理解 int *& r = p 的方法,是从右往左理解:

  • 等号右边,是 int* 类型
  • 等号左边,最右侧的 type modifier 是&, 说明 r 是一个引用类型
  • 剩余部分是 int* , 意思是 base_type 是 int*.
    在这里插入图片描述

总结

Compound Type 复合类型指的是基于其他类型定义的类型,C++中最基本的复合类型有两类:指针类型, 引用类型。

回顾和提升了对于变量声明的格式,以往的简单声明,格式是 type name; 现在则改为 base_type <type_modifier> name, 其中 type_modifier 在本章是 *& 两种,分别表示指针 和 引用(左值引用)。

也可以复合了 *& 使用,意思是指针类型的引用类型,如

int a = 3;
int* b = &a;
int*& c = b;

其中 c 是引用类型,base_type 是 int*.

提到了引用类型必须初始化,因为绑定到了已经存在的对象,引用则不会创建新的对象。

提到了指针可以不初始化,但是对于 block scope(大括号)内的没有初始化的指针,是undefined,建议避免; 也就是说C++语言标准,和编译器,都推卸了责任,这是C++程序出现运行时异常的一个重要缺口,由C++程序开发者背锅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值