当前位置: 首页 > article >正文

面试问题--智能指针

什么是智能指针?

当你在编写程序时,可能需要在运行时动态分配内存来存储数据。在传统的C++中,你可能会使用 new 和 delete 操作符来手动管理内存。但是这样容易出现一些问题,比如忘记释放内存导致内存泄漏,或者释放了之后仍然使用已经释放的内存(悬空指针问题)。
智能指针是为了解决这些问题而引入的。它们是一种封装了动态分配内存的对象,具有自动内存管理的功能。C++标准库提供了两种主要的智能指针类型:std::shared_ptr 和 std::unique_ptr。

  • std::shared_ptr : 允许多个智能指针共享同一块内存,使用引用计数来跟踪共享情况。
  • std::unique_ptr 保证在任何时候只有一个智能指针可以管理特定的内存块,支持独占所有权。

1.std::shared_ptr:

  • std::shared_ptr 允许多个智能指针共享同一块内存。
  • 每个 shared_ptr 都有一个关联的引用计数,记录有多少个 shared_ptr 指向相同的内存。
  • 当引用计数变为零时,表示没有智能指针再指向这块内存,内存会被释放。
#include <memory>

int main() {
    // 创建一个 shared_ptr,它指向一个动态分配的整数
    std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);

    // 创建另一个 shared_ptr,与前一个共享同一块内存
    std::shared_ptr<int> anotherSharedPtr = sharedPtr;

    // 引用计数为2,因为有两个 shared_ptr 指向相同的内存

    // ...
    // 当最后一个指向内存的 shared_ptr 被销毁时,内存会被释放
    return 0;
}

2.std::unique_ptr:

  • std::unique_ptr 确保在任何时候只有一个智能指针可以管理特定的内存块。
  • 不能直接复制或赋值 unique_ptr,因为这违反了“独占所有权”的原则。
  • 当 unique_ptr 被销毁时,它所管理的内存也会被释放。
#include <memory>

int main() {
    // 创建一个 unique_ptr,它独占一个动态分配的整数
    std::unique_ptr<int> uniquePtr = std::make_unique<int>(42);

    // 不能这样做,因为这违反了独占所有权的原则
    // std::unique_ptr<int> anotherUniquePtr = uniquePtr;

    // ...
    // 当 uniquePtr 被销毁时,它所管理的内存会被释放
    return 0;
}

使用智能指针的C++图形应用程序

在现代C++中,智能指针是一种强大的工具,用于更安全和方便地管理动态内存。本文将演示一个简单的图形应用程序示例,展示如何使用 std::shared_ptrstd::unique_ptr 来管理图形对象的内存。

实际应用示例

假设我们正在编写一个图形应用程序,需要处理不同类型的图形对象。我们将创建一个简单的图形类层次结构,并使用智能指针来管理这些对象的内存。

#include <iostream>
#include <memory>
#include <vector>

// 抽象基类 Shape
class Shape {
public:
    virtual void draw() const = 0;
    virtual ~Shape() {
        std::cout << "Shape Destructor" << std::endl;
    }
};

// 派生类 Circle
class Circle : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a Circle" << std::endl;
    }
    ~Circle() {
        std::cout << "Circle Destructor" << std::endl;
    }
};

// 派生类 Square
class Square : public Shape {
public:
    void draw() const override {
        std::cout << "Drawing a Square" << std::endl;
    }
    ~Square() {
        std::cout << "Square Destructor" << std::endl;
    }
};

int main() {
    // 使用 shared_ptr 管理 Shape 对象的动态分配内存
    std::shared_ptr<Shape> circlePtr = std::make_shared<Circle>();
    std::shared_ptr<Shape> squarePtr = std::make_shared<Square>();

    // 使用 unique_ptr 管理 Shape 对象的动态分配内存
    std::unique_ptr<Shape> anotherCirclePtr = std::make_unique<Circle>();

    // 将智能指针存储在容器中
    std::vector<std::shared_ptr<Shape>> shapes;
    shapes.push_back(circlePtr);
    shapes.push_back(squarePtr);
    
    // 使用 std::move 将所有权转移给容器
    shapes.push_back(std::move(anotherCirclePtr));

    // 调用 draw 方法
    for (const auto& shape : shapes) {
        shape->draw();
    }

    // 当 main 函数结束时,所有的智能指针将被销毁,从而释放相关内存

    return 0;
}


http://www.kler.cn/a/148859.html

相关文章:

  • Android 13 实现屏幕熄屏一段时候后关闭 Wi-Fi 和清空多任务列表
  • 67页PDF |埃森哲_XX集团信息发展规划IT治理优化方案(限免下载)
  • 家政服务小程序,家政行业数字化发展下的优势
  • Spring——事务
  • 前端js用canvas合成图片并转file对象
  • 如何向函数模块 FM 中传递 Range 参数
  • linux网络编程之UDP编程
  • 详细讲解1.js处理日期对象输出标准的“2000年12月22日 周三“ 的格式
  • 杂记 | 使用Docker安装并配置MongoDB以支持事务(单副本,并解决了证书文件错误的问题)
  • centos7.9 + gitlab12.3.0安装
  • PyQt6 QLineEdit单行文本框控件
  • 使用python提取出身份证的出生日期(18位和15位)
  • C# freesql技术 常用的增删改查sql命令
  • linux安装终端连接工具Tabby
  • DjiTello + YoloV5的无人机的抽烟检测
  • 创建Dataloader基础篇【一】
  • 拆解按摩器:有意思的按键与LED控制电路,学习借鉴一下!
  • <Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux 进程管理 9》(13)
  • IELTS学习笔记_grammar_新东方
  • 基于MBC调制方法的准Z源三相逆变器Simulink建模与仿真
  • 目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】特征点检测与匹配
  • MySQL慢查询
  • Flink Flink中的合流
  • Python---lambda表达式
  • 交换机的VRRP主备配置例子
  • 计网Lesson3 - 计算机网络评价指标与封包解包