指针以及指针的分类

指针就是有指向的变量,它指向的是和存储指针本身类型相同的变量的空间,指针有多级指针,以及指针直接指向变量存放空间,二级指针指向的是存放同类型一级指针的空间,多级类推二级指向一级一样指向它的前一级指针存放空间,下面在介绍指针的分类之前我简单的通过画图展示一下指针和变量之间、指针和指针之间的指向关系:
这里写图片描述
在图片中可以看出有整型变量和整型一级和二级指针,一级指针指向了变量a,二级指针q指向了以及指针p,在图片里也不难看出指针里存放的是地址,这就是为什么通过指针能找到它指向的变量,而且还能更改它的值,下面一段代码体现:

#include<iostream>

using namespace std;
int main()
{
    int a = 10;
    int *p = &a;
    int **q = &p;
    cout<<"a = "<<a<<endl;
    cout<<"*p = "<<*p<<endl;
    cout<<"**q = "<<**q<<endl;
    cout<<"////////////通过一级指针改变////////////////"<<endl;
    *p = 2;
    cout<<"a = "<<a<<endl;
    cout<<"*p = "<<*p<<endl;
    cout<<"**q = "<<**q<<endl;
    cout<<"////////////通过二级指针改变////////////////"<<endl;
    **q = 8;
    cout<<"a = "<<a<<endl;
    cout<<"*p = "<<*p<<endl;
    cout<<"**q = "<<**q<<endl;
    return 0;
}

这里写图片描述
这里的二级指针改变和一级是一样的,我们都知道p是取p所指向空间的值就是a,那么*q是不是取q所指向的空间的值p,那么我们把q指针q)这样写我想能更好理解点,既然*q和p是相等的,那么(*q)是不是就是*p了,那么是不是通过**q同样可以指向a,只不过是中间借鉴了一个一级指针而已。
在经过上述阅读后我相信哪怕是没有学过指针的同学对指针应该有了认识,那么接下来我们来说说指针的分类,指针按照他们的属性可分为三类:

1. 原生指针

 就是最普通的指针,定义类似: 类型 *变量名;
 与之对比的是使用上有类似指针的功能 实际并不是指针。比如:迭代器
 [一个类重载 *和->操作符 那么可以像指针一样使用  但是这种并不是原生的]

2. 泛型指针

 第一种就是 void *指针 可以指向任意的数据结构 因此可以称为"泛型"。
 第二种就是指具有指针特性的泛型数据结构 如:泛型迭代器和接下来要说的智能指针。

3. 智能指针

 C++中没有自动回收内存的机制,因此出现了智能指针。
      一般我们将一个指针封装到一个智能指针类中,该类中有一个引用计数器。
      对指针的复制等操作会使引用计数+1,delete操作会使引用计数-1。
 希望阅读完这篇博客对你学习指针有所帮助,指针是很多语言的基本技能,所以在学好指针必须了解指针的两值四方面,如果有人需要可以留言我有一本电子版资料讲的就是指针是我师傅自己写的,通俗易懂可以给你发过去。     
<think>我们正在讨论C++中的指针类型及其特性。根据引用内容,特别是引用[2]和引用[4],我们可以知道C++标准库提供了三种主要的智能指针:`std::unique_ptr`、`std::shared_ptr`和`std::weak_ptr`。此外,C++还支持传统的裸指针(raw pointer)。因此,我们可以将C++指针分为两大类:智能指针和裸指针。下面我将详细说明各类指针的特性。 ### 1. 裸指针(Raw Pointers) 裸指针是C++中最基础的指针类型,它直接存储内存地址。裸指针不管理所指向对象的生命周期,需要程序员手动分配和释放内存。裸指针的特性包括: - **直接内存访问**:裸指针可以直接访问和修改内存。 - **灵活性高**:可以指向任意类型的数据,包括数组、函数等。 - **风险高**:容易导致内存泄漏、悬垂指针、野指针等问题。 ### 2. 智能指针(Smart Pointers) 智能指针是C++11引入的,用于自动管理动态分配的内存资源,通过RAII(Resource Acquisition Is Initialization)机制确保资源在适当的时候被释放。智能指针包括以下三种: #### (1) `std::unique_ptr` - **独占所有权**:同一时间只能有一个`unique_ptr`指向特定的对象。当`unique_ptr`被销毁时,它所指向的对象也会被自动销毁。 - **不可复制**:不能复制`unique_ptr`,但可以通过移动语义转移所有权。 - **内存占用小**:通常只包含一个指向堆对象的指针,几乎没有额外开销。 - **适用场景**:适用于资源独占的场景,如工厂函数的返回值[^4]。 #### (2) `std::shared_ptr` - **共享所有权**:多个`shared_ptr`可以指向同一个对象,通过引用计数管理对象的生命周期。当最后一个`shared_ptr`被销毁时,对象才会被销毁。 - **支持复制**:可以通过复制构造或赋值操作共享所有权。 - **额外开销**:引用计数存储在堆上,因此有额外的内存和时间开销。 - **适用场景**:适用于需要多个指针共享同一资源的场景。 #### (3) `std::weak_ptr` - **弱引用**:`weak_ptr`指向由`shared_ptr`管理的对象,但不增加引用计数。因此,它不会阻止所指向对象的销毁。 - **解决循环引用**:主要用于解决`shared_ptr`之间的循环引用问题。 - **需要转换为`shared_ptr`**:要访问对象,必须将`weak_ptr`转换为`shared_ptr`(通过`lock()`方法),以确保对象在访问期间存在。 - **适用场景**:适用于需要观察共享资源但不拥有所有权的场景,如缓存、观察者模式等。 ### 总结 C++中的指针类型主要分为裸指针和智能指针两大类。裸指针提供直接的内存访问,但需要手动管理内存;智能指针则自动管理内存,提高了代码的安全性和可靠性。其中,`std::unique_ptr`用于独占资源,`std::shared_ptr`用于共享资源,`std::weak_ptr`用于解决共享指针的循环引用问题。在实际开发中,应优先使用智能指针来避免内存管理错误[^1][^2]。 §§相关问题§§ 1. 智能指针如何解决内存泄漏问题? 2. 在什么情况下应该使用`std::weak_ptr`? 3. `std::unique_ptr`和`std::shared_ptr`在性能上有何差异? 4. 裸指针在C++现代编程中还有哪些应用场景?</think>### C++指针类型及特性详解 #### 一、裸指针(Raw Pointers) 1. **基本特性** - 直接存储内存地址:`int* ptr = &var;` - **不管理生命周期**:需手动分配/释放内存(`new`/`delete`) - 高风险:易导致内存泄漏、悬垂指针、野指针 - 示例: ```cpp int* p = new int(10); // 手动分配 delete p; // 手动释放 ``` #### 二、智能指针(C++11引入) > 通过RAII(资源获取即初始化)自动管理资源生命周期[^1] 1. **`std::unique_ptr`(独占指针)** - **特性**: - 独占所有权:同一时刻仅一个指针可持有对象 - 不可复制(可通过`std::move`转移所有权) - 零额外开销(与裸指针相同的内存占用)[^4] - **适用场景**: ```cpp auto uptr = std::make_unique<int>(20); // C++14推荐 // auto uptr2 = uptr; // 错误!不可复制 auto uptr3 = std::move(uptr); // 所有权转移 ``` 2. **`std::shared_ptr`(共享指针)** - **特性**: - 共享所有权:多个指针可指向同一对象 - 引用计数:自动销毁对象(计数归零时) - 支持复制:`auto sptr2 = sptr1;` - **内存开销**:包含两个指针(对象指针 + 控制块指针)[^2] - **循环引用风险**:需结合`weak_ptr`解决 - 示例: ```cpp auto sptr = std::make_shared<int>(30); ``` 3. **`std::weak_ptr`(弱指针)** - **特性**: - 观察者模式:不增加引用计数 - 解决`shared_ptr`循环引用问题 - 需通过`lock()`转换为`shared_ptr`访问对象 - **典型用法**: ```cpp std::weak_ptr<int> wptr = sptr; if (auto tmp = wptr.lock()) { // 安全访问 std::cout << *tmp; } ``` #### 三、指针特性对比表 | 类型 | 所有权 | 是否可复制 | 内存开销 | 线程安全 | |---------------|------------|------------|----------|----------------| | 裸指针 | 无 | 是 | 无 | 不安全 | | `unique_ptr` | 独占 | 否(可移动)| 无 | 安全(单个实例)| | `shared_ptr` | 共享 | 是 | 中 | 引用计数原子操作[^2] | | `weak_ptr` | 无(观察) | 是 | 中 | 安全 | #### 四、使用建议 1. **优先选择智能指针**:避免手动内存管理错误[^1] 2. **场景适配**: - 独占资源 → `unique_ptr` - 共享资源 → `shared_ptr` + `weak_ptr`(防循环引用) 3. **避免混用**:智能指针与裸指针不要交叉管理同一资源 4. **工厂模式**:`unique_ptr`作为工厂函数返回值[^4] > 关键原则:**所有权语义明确化**是安全使用指针的核心[^1][^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值