C++系列5:指针和引用
发布日期:2021-05-08 09:43:37 浏览次数:21 分类:精选文章

本文共 2655 字,大约阅读时间需要 8 分钟。

1 【重要】指针声明

Bjarne 在他的 The C++ Programming Language 里面给出过一个助记的方法: 把一个声明从右向左读

char  * const cp; ( * 读成 pointer to ) //cp is a const pointer to char const char * p; //p is a pointer to const char; char const * p;//同上因为 C++ 里面没有 const* 的运算符,所以 const 只能属于前面的类型。

2 引用

int& r = i;int r = i;不同之处应该是内存的分配吧,后者会再开辟一个内存空间。

引用必须在声明时将其初始化,不能先声明后赋值。

int rats = 10;int &rodents = rats;

上面代码实际上是下述代码的伪装表示:

int rats = 10;int * const pr = &rats;

3 指向结构体的指针

您可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:

struct Books *struct_pointer;
现在,您可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,如下所示:
struct_pointer = &Book1;
为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,如下所示:
struct_pointer->title;
下面是完整例子:

#include 
#include
using namespace std;void printBook( struct Books *book ); struct Books{ char title[50]; char author[50]; char subject[100]; int book_id;}; int main( ){ Books Book1; // 定义结构体类型 Books 的变量 Book1 Books Book2; // 定义结构体类型 Books 的变量 Book2 // Book1 详述 strcpy( Book1.title, "C++ 教程"); strcpy( Book1.author, "Runoob"); strcpy( Book1.subject, "编程语言"); Book1.book_id = 12345; // Book2 详述 strcpy( Book2.title, "CSS 教程"); strcpy( Book2.author, "Runoob"); strcpy( Book2.subject, "前端技术"); Book2.book_id = 12346; // 通过传 Book1 的地址来输出 Book1 信息 printBook( &Book1 ); // 通过传 Book2 的地址来输出 Book2 信息 printBook( &Book2 ); return 0;}// 该函数以结构指针作为参数void printBook( struct Books *book ){ cout << "书标题 : " << book->title <
author <
subject <
book_id <

注意这里输入函数必须用struct Books,一种简化方式是用typedef

typedef struct Books{   char  title[50];   char  author[50];   char  subject[100];   int   book_id;}Books;

4 智能指针

为了既能最大程度的避免内存泄漏又能兼顾效率,C++11标准引入了智能指针shared_ptr和unique_ptr。

4.1 shared_ptr

通常来说,动态申请了一片内存之后,可能会在多个地方会用到,对于裸指针,你需要自己记住在什么地方释放内存,不能在有别的地方还在使用的时候,你就释放,也不能忘记释放。如果是这样,为什么不在有人用的时候,就增加引用计数,而不用的时候(离开作用域或者生命周期外)就较少引用计数呢,如果引用计数为0,则自动释放内存。

举个通俗的例子,假设一个房间里有自动感应灯光。有人在的时候,灯亮了(申请使用内存),再来一个人,这个灯还是亮着,人数增加,而这两个人走掉的时候,房间空了,感应不到人(引用计数为0)的时候,灯就可以自动灭了(自动释放内存),这样也就最大程度地利用了灯光。
不过它的实现要考虑的因素很多,例如如何原子地增加引用计数。所以它在一定程度上比裸指针开销要大。
下面是三种常见的定义shared_ptr的方式:

shared_ptr
sp;//使用reset方式,声明一个指向int类型的智能指针sp.reset(new int(42));auto sp1 = make_shared
("hello");//使用make_shared方式shared_ptr sp2(new int(42));//使用构造函数的方式

make_shared方式是推荐的一种,它使用一次分配,比较安全。

4.2 unique_ptr

与shared_ptr不同,unique_ptr专属某个对象资源。也就是说,如果某个对象有一个专属管理,它不能被复制,那么当这个专属管理不再使用的时候,就可以自动释放内存了。

同样一个通俗的例子,我们现在在很多洗手间都可以看到自动感应的水龙头,一个水龙头通常只供一个人使用(申请并占用资源),而当这个人离开的时候,水龙头自动关闭(自动释放内存)。
而对于老式的水龙头,一旦忘了关了(好像一般也不会忘),就会一直浪费水。

4.3 weak_ptr

还有一种情况,对于某些对象,如它可能作为缓存。它有的时候,我就用一下,没有的时候就不用,也不负责去管理资源的释放资源,岂不美哉?

上一篇:C++系列6:多线程
下一篇:C++系列4:数据类型和变量

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月16日 17时05分42秒