Boost 智能指针
scoped_ptr
不能被复制或赋值给其他 scoped_ptr 对象,不能与其他指针比较 (除了 nullptr)
scoped_ptr 用例
template <typename T>
class scoped_ptr {
public:// 构造函数:初始化 scoped_ptr 并接管指针的所有权explicit scoped_ptr(T* ptr = nullptr) : ptr_(ptr) {}// 析构函数:释放管理的对象~scoped_ptr() {delete ptr_;}// 禁止复制构造函数和赋值操作符scoped_ptr(const scoped_ptr&) = delete;scoped_ptr& operator=(const scoped_ptr&) = delete;// 移动构造函数和移动赋值操作符scoped_ptr(scoped_ptr&& other) noexcept : ptr_(other.release()) {}scoped_ptr& operator=(scoped_ptr&& other) noexcept {if (this != &other) {reset(other.release());}return *this;}// 重载解引用操作符T& operator*() const {return *ptr_;}// 重载箭头操作符T* operator->() const {return ptr_;}// 获取管理的指针T* get() const {return ptr_;}// 释放管理的指针并返回T* release() {T* tmp = ptr_;ptr_ = nullptr;return tmp;}// 重置管理的指针void reset(T* ptr = nullptr) {if (ptr_ != ptr) {delete ptr_;ptr_ = ptr;}}// 检查是否管理一个非空指针explicit operator bool() const {return ptr_ != nullptr;}private:T* ptr_;
};
unique_ptr
头文件<boost/smart_ptr/make_unique.hpp>里实现了make_unique()函数,位于名字空间 boost 而不是 std,为了避免潜在的冲突。
unique_ptr 用例
创建单个对象
#include <memory>struct MyClass {MyClass(int x, double y) : x_(x), y_(y) {}int x_;double y_;
};int main() {auto ptr = std::make_unique<MyClass>(42, 3.14);// ptr is a std::unique_ptr<MyClass>return 0;
}
创建数组
#include <memory>int main() {auto arr = std::make_unique<int[]>(10);// arr is a std::unique_ptr<int[]> with 10 elementsreturn 0;
}
函数中返回动态分配的对象
#include <memory>std::unique_ptr<int> createInt(int value) {return std::make_unique<int>(value);
}int main() {auto ptr = createInt(42);// ptr is a std::unique_ptr<int>return 0;
}
容器中存储动态分配的对象
#include <memory>
#include <vector>int main() {std::vector<std::unique_ptr<int>> vec;vec.push_back(std::make_unique<int>(1));vec.push_back(std::make_unique<int>(2));vec.push_back(std::make_unique<int>(3));// vec contains std::unique_ptr<int> elementsreturn 0;
}
避免资源泄漏
#include <memory>void process(std::unique_ptr<int> ptr) {// Do something with ptr
}int main() {auto ptr = std::make_unique<int>(42);process(std::move(ptr)); // No need to manually delete the pointerreturn 0;
}
shared_ptr
引用计数型的智能指针,可以被自由地拷贝和赋值,可以在任意的地方共享它,当没有代码使用它时(引用计数为0),才删除被包装的动态分配的对象。
shared_ptr 用例
- 函数中返回动态分配的对象
- 容器中存储动态分配的对象
- 避免资源泄漏
创建单个对象
#include <memory>struct MyClass {MyClass(int x, double y) : x_(x), y_(y) {}int x_;double y_;
};int main() {auto ptr = std::make_shared<MyClass>(42, 3.14);// ptr is a std::shared_ptr<MyClass>return 0;
}
创建数组(C++20)
#include <memory>int main() {auto arr = std::make_shared<int[]>(10);// arr is a std::shared_ptr<int[]> with 10 elementsreturn 0;
}
shared_ptr 应用于标准容器
shared_ptr 作为容器的元素
#include <iostream>
#include <memory>
#include <vector>class MyClass {
public:MyClass(int id) : id_(id) {std::cout << "Constructing MyClass " << id_ << std::endl;}~MyClass() {std::cout << "Destroying MyClass " << id_ << std::endl;}void print() const {std::cout << "MyClass " << id_ << std::endl;}
private:int id_;
};int main() {std::vector<std::shared_ptr<MyClass>> vec;// 创建并存储 shared_ptr 对象for (int i = 0; i < 5; ++i) {vec.push_back(std::make_shared<MyClass>(i));}// 使用 shared_ptr 对象for (const auto& ptr : vec) {ptr->print();}return 0;
}
容器作为 shared_ptr 的管理对象
#include <iostream>
#include <memory>
#include <vector>class MyClass {
public:MyClass(int id) : id_(id) {std::cout << "Constructing MyClass " << id_ << std::endl;}~MyClass() {std::cout << "Destroying MyClass " << id_ << std::endl;}void print() const {std::cout << "MyClass " << id_ << std::endl;}
private:int id_;
};int main() {// 创建一个 shared_ptr 管理 vector 容器auto vecPtr = std::make_shared<std::vector<std::shared_ptr<MyClass>>>();// 向 vector 中添加 MyClass 对象for (int i = 0; i < 5; ++i) {vecPtr->push_back(std::make_shared<MyClass>(i));}// 使用 vector 中的 MyClass 对象for (const auto& ptr : *vecPtr) {ptr->print();}return 0;
}
桥接模式
#include <iostream>
#include <memory>// 渲染器接口
class Renderer {
public:virtual ~Renderer() = default;virtual void renderCircle(float x, float y, float radius) = 0;virtual void renderRectangle(float x, float y, float width, float height) = 0;
};// OpenGL 渲染器
class OpenGLRenderer : public Renderer {
public:void renderCircle(float x, float y, float radius) override {std::cout << "OpenGL rendering circle at (" << x << ", " << y << ") with radius " << radius << std::endl;}void renderRectangle(float x, float y, float width, float height) override {std::cout << "OpenGL rendering rectangle at (" << x << ", " << y << ") with width " << width << " and height " << height << std::endl;}
};// DirectX 渲染器
class DirectXRenderer : public Renderer {
public:void renderCircle(float x, float y, float radius) override {std::cout << "DirectX rendering circle at (" << x << ", " << y << ") with radius " << radius << std::endl;}void renderRectangle(float x, float y, float width, float height) override {std::cout << "DirectX rendering rectangle at (" << x << ", " << y << ") with width " << width << " and height " << height << std::endl;}
};// 形状接口
class Shape {
public:Shape(std::shared_ptr<Renderer> renderer) : renderer_(renderer) {}virtual ~Shape() = default;virtual void draw() = 0;
protected:std::shared_ptr<Renderer> renderer_;
};// 圆形
class Circle : public Shape {
public:Circle(std::shared_ptr<Renderer> renderer, float x, float y, float radius): Shape(renderer), x_(x), y_(y), radius_(radius) {}void draw() override {renderer_->renderCircle(x_, y_, radius_);}
private:float x_, y_, radius_;
};// 矩形
class Rectangle : public Shape {
public:Rectangle(std::shared_ptr<Renderer> renderer, float x, float y, float width, float height): Shape(renderer), x_(x), y_(y), width_(width), height_(height) {}void draw() override {renderer_->renderRectangle(x_, y_, width_, height_);}
private:float x_, y_, width_, height_;
};int main() {auto openglRenderer = std::make_shared<OpenGLRenderer>();auto directxRenderer = std::make_shared<DirectXRenderer>();Circle circle1(openglRenderer, 10, 10, 5);Rectangle rectangle1(openglRenderer, 20, 20, 15, 10);Circle circle2(directxRenderer, 30, 30, 7);Rectangle rectangle2(directxRenderer, 40, 40, 20, 15);circle1.draw();rectangle1.draw();circle2.draw();rectangle2.draw();return 0;
}
weak_ptr
不具有普通指针的行为,没有重载 operator* 和 ->。weak_ptr 被设计为与 shared_ptr 协同工作,可以从一个 shared_ptr 或另一个 weak_ptr 对象构造以获得资源的观测权。但 weak_ptr 没有共享资源,它的构造不会引起指针引用计数的增加。
weak_ptr 用例
#include <iostream>
#include <memory>int main() {std::shared_ptr<int> shared = std::make_shared<int>(42);std::weak_ptr<int> weak = shared;if (auto locked = weak.lock()) {std::cout << "Object still exists: " << *locked << std::endl;} else {std::cout << "Object has been destroyed." << std::endl;}shared.reset(); // 释放 shared_ptr,对象被销毁if (auto locked = weak.lock()) {std::cout << "Object still exists: " << *locked << std::endl;} else {std::cout << "Object has been destroyed." << std::endl;}return 0;
}
打破循环引用
class node
{
public:~node(){std::cout << "deleted" << std::endl;}typedef weak_ptr<node> ptr_type;//typedef shared_ptr<node> ptr_type;ptr_type next;
};void case3()
{auto p1 = make_shared<node>();auto p2 = make_shared<node>();p1->next = p2;p2->next = p1;assert(p1.use_count() == 1);assert(p2.use_count() == 1);if(!p1->next.expired()){auto p3 = p1->next.lock();}
}
相关文章:
Boost 智能指针
scoped_ptr 不能被复制或赋值给其他 scoped_ptr 对象,不能与其他指针比较 (除了 nullptr) scoped_ptr 用例 template <typename T> class scoped_ptr { public:// 构造函数:初始化 scoped_ptr 并接管指针的所有权explicit scoped_ptr(T* ptr n…...
在WSL Ubuntu中启用root用户的SSH服务
在 Ubuntu 中,默认情况下 root 用户是禁用 SSH 登录的,这是为了增加系统安全性。 一、修改配置 找到 PermitRootLogin 行:在文件中找到 PermitRootLogin 配置项。默认情况下,它通常被设置为 PermitRootLogin prohibit-password 或…...
C语⾔数据类型和变量
C语⾔数据类型和变量 1.数据类型介绍1.1 字符型1.2 整型1.3 浮点型1.4 布尔类型1.5 各种数据类型的长度1.5.1 sizeof操作符1.5.2 数据类型长度1.5.3 sizeof中表达式不计算 2. signed 和 unsigned3. 数据类型的取值范围4. 变量4.1 变量的创建4.2 变量的分类 5. 算术操作符&#…...
运行时类型信息(RTTI)
在计算机编程中,运行时类型信息(Runtime Type Information,简称RTTI)或运行时类型标识(Runtime Type Identification)是某些编程语言(如C++、Object Pascal、Ada)的一个特性,它允许在程序运行时获取对象的数据类型信息。RTTI可以用于所有类型,也只能用于显式启用RTTI…...
使用 NVivo 定性数据分析软件指导癌症护理研究
您是否曾因进行全面文献综述所需的大量研究而感到不知所措?在比较和整理大量冗长的出版物时,您是否不知道从哪里开始?幸运的是,这正是定性研究专家 Heidi Rishel Brakey 硕士擅长的领域,我们将在本案例研究中介绍这一点…...
R语言 | 使用ggplot绘制柱状图,在柱子中显示数值和显著性
原文链接:使用ggplot绘制柱状图,在柱子中显示数值和显著性 本期教程 获得本期教程示例数据,后台回复关键词:20240628。(PS:在社群中,可获得往期和未来教程所有数据和代码) 往期教程…...
第十四届蓝桥杯省赛C++B组D题【飞机降落】题解(AC)
解题思路 这道题目要求我们判断给定的飞机是否都能在它们的油料耗尽之前降落。为了寻找是否存在合法的降落序列,我们可以使用深度优先搜索(DFS)的方法,尝试所有可能的降落顺序。 首先,我们需要理解题目中的条件。每架…...
容器化spring boot应用程序
容器化spring boot应用程序有多种方式,如基于简单的Dockerfile,多阶段Dockerfile以及基于Docker Compose等,我们将逐步给大家介绍,本节主要介绍基于简单的Dockerfile进行容器化spring boot的应用程序。 创建Spring boot应用程序 …...
掌握智慧校园:资产来源功能解析
在智慧校园的资产管理框架下,资产来源管理是确保资产数据完整性和合规性的重要一环。这一功能通过数字化手段,详尽记录每一项资产从何而来,无论是采购、捐赠、内部调拨,还是自制与改造,均需经过严格记录与追踪…...
基于公有云部署wordpress
云平台选择 腾讯云 阿里云 华为云 项目部署 一、架构讲解 1.1、定义与组成 LNMP是Linux、Nginx、MySQL(或MariaDB)和PHP(或Perl、Python)的首字母缩写,代表在Linux系统下使用Nginx作为Web服务器,MySQL作为…...
vite+vue集成cesium
1、创建项目、选择框架vuejs pnpm create vite demo_cesium 2、进入项目安装依赖 cd demo_cesium pnpm install3、安装cesium及插件 3、pnpm i cesium vite-plugin-cesium 4、修改vite-config.js import { defineConfig } from vite import vue from vitejs/plugin-vue impo…...
2024 年江西省研究生数学建模竞赛A题:交通信号灯管理问题分析、实现代码及参考论文
2024 年江西省研究生数学建模竞赛题目交通信号灯管理 1 题目 交通信号灯是指挥车辆通行的重要标志,由红灯、绿灯、 黄灯组成。红灯停、绿灯行,而黄灯则起到警示作用。交通 信号灯分为机动车信号灯、非机动车信号灯、人行横道信号 灯、方向指示灯等。 一…...
华为机试HJ1字符串最后一个单词的长度
华为机试HJ1字符串最后一个单词的长度 题目: 计算字符串中最后一个单词的长度 想法: 利用空格将字符串中的单词进行切分,返回最后一个单词的长度 input_str input() # 字符串输入 result input_str.split(" ")[-1] # 选取…...
排序(冒泡排序、选择排序、插入排序、希尔排序)-->深度剖析(一)
欢迎来到我的Blog,点击关注哦💕 前言 排序是一种基本的数据处理操作,它涉及将一系列项目重新排列,以便按照指定的标准(通常是数值大小)进行排序。在C语言中,排序算法是用来对元素进行排序的一系…...
(2024)docker-compose实战 (6)部署前端项目(react, vue)
前言 本次仅使用nginx搭建单一的前端项目, 前端项目可以是html, react, vue.项目目录中需要携带nginx的配置文件(conf/default.conf).前端文件直接拷贝到项目目录中即可.如果不确定镜像的配置文件目录, 可以通过 docker inspect 镜像名 来查看具体的配置信息.使用docker-compos…...
python 中的 下划线_ 是啥意思
在 Python 中,_(下划线)通常用作占位符,表示一个变量名,但程序中不会实际使用这个变量的值。 目录 忽略循环变量:忽略函数返回值:在解释器中使用:举例子1. 忽略循环变量2. 忽略不需…...
Solana公链
Solana是一个高性能的区块链平台,其设计目标是在不牺牲去中心化或安全性的情况下提供可扩展性。Solana由前高通、英特尔及Dropbox的工程师于2017年末创立。以下是Solana的一些关键特点: 高吞吐量:Solana能够每秒处理高达65,000笔交易…...
【LeetCode】反转字符串中的单词
目录 一、题目二、解法完整代码 一、题目 给你一个字符串 s ,请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意࿱…...
[leetcode]文件组合
. - 力扣(LeetCode) class Solution { public:vector<vector<int>> fileCombination(int target) {vector<vector<int>> vec;vector<int> res;int sum 0, limit (target - 1) / 2; // (target - 1) / 2 等效于 target /…...
数据库断言
预期值和实际值做对比 步骤: 1、得到表格数据 2、接口断言预期值与实际值做对比 读取表格数据-得到接口地址(address)和是否接口db检查(dbcheck),并且这条数据是有效的(vaild) 有2条用例,也会有三个条件不全部满足的情况&…...
D3KeyHelper终极指南:5分钟上手暗黑3智能宏,轻松提升游戏体验
D3KeyHelper终极指南:5分钟上手暗黑3智能宏,轻松提升游戏体验 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏…...
OpenClaw Gateway智能守护者:双触发自愈与AI诊断实践
1. 项目概述:一个为OpenClaw Gateway设计的智能守护者如果你在运维一个基于OpenClaw Gateway的服务,大概率经历过这样的深夜惊魂:手机突然收到告警,提示网关服务挂了,然后你不得不从床上爬起来,摸黑打开电脑…...
电磁兼容(EMC)设计实战:从干扰源头到系统防护的完整指南
1. 电磁兼容(EMC)设计的核心逻辑 电磁兼容设计就像给电子设备打造一套"防干扰盔甲"。想象一下,你正在用手机通话时,突然听到收音机杂音——这就是典型的电磁干扰现象。EMC设计要解决两个核心问题:不让自家设…...
R3nzSkin英雄联盟皮肤修改器:深入解析开源内存注入技术实现
R3nzSkin英雄联盟皮肤修改器:深入解析开源内存注入技术实现 【免费下载链接】R3nzSkin Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3n/R3nzSkin R3nzSkin 是一款基于内存注入技术的英雄联盟皮肤修改工具ÿ…...
2026年搜索引擎大变革:生成式优化解决方案引领新潮流
引言随着ChatGPT、Google AI概览等工具成为主流搜索界面,传统的SEO策略已难以适配新时代的挑战。生成式引擎优化(GEO)应运而生,成为企业在线上生存与优化的新选择。本文将探讨2026年SEO行业格局的变化,分析GEO的核心逻…...
艾尔登法环风灵月影修改器下载(已汉化)分享2026最新版
《艾尔登法环》以交界地为舞台,打造了一款兼具开放世界探索与高难度挑战的角色扮演游戏。玩家将扮演褪色者,在破碎的土地上冒险,挑战强大敌人、收集装备、提升能力,最终成为艾尔登之王。游戏以硬核战斗与开放探索为核心࿰…...
AI大模型赋能数据治理:小白也能掌握的5个高频场景与避坑指南(收藏备用)
数据治理是企业数字化转型难题,AI大模型带来破局点。本文阐述大模型如何解决效率低、门槛高、适配弱等痛点,提供3个高价值落地场景(非结构化数据治理、数据质量治理、数据资产化治理)及5个高频踩坑陷阱,并给出最佳实践…...
如何在Windows上轻松安装APK文件:告别模拟器的完整指南
如何在Windows上轻松安装APK文件:告别模拟器的完整指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想要在Windows电脑上直接运行Android应用…...
告别混乱!用Cadence Allegro SPB17.4从DXF文件创建PCB封装的完整清洁流程
告别混乱!用Cadence Allegro SPB17.4从DXF文件创建PCB封装的完整清洁流程 在PCB设计领域,从机械图纸(DXF)快速创建精确的封装是工程师常面临的挑战。许多设计师都经历过这样的困扰:导入DXF后,封装在3D预览中…...
多云配置管理工具MCP:统一编排AWS、GCP等云资源的实战指南
1. 项目概述:一个高效的多云配置管理工具 最近在梳理团队的基础设施配置时,发现了一个挺有意思的开源项目,叫 malminhas/mcp 。乍一看这个名字,你可能会有点懵,这缩写代表什么?其实,MCP 在这里…...
