Boost 智能指针

news2024/7/4 6:22:06

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 elements
    return 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> elements
    return 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 pointer
    return 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 elements
    return 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();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1884083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE5(c++)开发日志(3):将前面写的输出日志的方法进行封装

Public下新增一个c类&#xff1a; 选择无属性&#xff0c;因为不需要添加任何东西进去, 也不需要借助里面任何东西。 创建一个命名空间Debug&#xff0c;可以在命名空间内写一点静态方法 &#xff1a; namespace Debug{} static void Print(const FString& message, con…

试用笔记之-汇通汉诺塔-益智游戏

首先下载汇通汉诺塔&#xff1a; http://www.htsoft.com.cn/download/HanoiTower.rar 汇通汉诺塔游戏规则:把X轴的圈圈都移到Z轴过关。 还可以选择自动游戏哦&#xff0c;看看AI机器人玩汇通汉诺塔

前程无忧滑块

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi …

启智畅想火车集装箱箱号识别系统,同时识别车皮号、火车底盘号码

1、应用背景 在现代物流体系中&#xff0c;铁路集装箱运输扮演着举足轻重的角色&#xff0c;目前各个铁路系统在管理集装箱车厢进出站时&#xff0c;方法传统&#xff0c;采用人工登记集装箱箱号、车皮号以及火车底盘号码的方式&#xff0c;效率低、错误率高、人员工作量大、信…

湖北大学2024年成人高考函授报名专升本会计学专业介绍

湖北大学&#xff0c;这所坐落于历史文化名城武汉的高等学府&#xff0c;自其创立之初&#xff0c;便秉持着“厚德博学&#xff0c;求是创新”的校训&#xff0c;致力于培养一代又一代的优秀人才。而今&#xff0c;为满足广大社会人士对高等教育的渴求&#xff0c;特别是那些已…

新的里程碑丨deepin校园联盟在拉丁美洲自由软件节上的国际风采

deepin校园联盟秉持推广开源文化与技术的宗旨&#xff0c;在全球技术交流的洪流中&#xff0c;再次于海外掀起热烈浪潮。在厄瓜多尔雅才理工大学&#xff08;Yachay Tech University&#xff09;&#xff0c;deepin校园联盟大使Mosquera率领团队&#xff0c;跨越数百公里之遥&a…

Jenkins教程-12-发送html邮件测试报告

上一小节我们学习了发送钉钉测试报告通知的方法&#xff0c;本小节我们讲解一下发送html邮件测试报告的方法。 1、自动化用例执行完后&#xff0c;使用pytest_terminal_summary钩子函数收集测试结果&#xff0c;存入本地status.txt文件中&#xff0c;供Jenkins调用 #conftest…

Optional类方法

Optional类 方法empty()方法of(T value)ofNullable(T value)filter(Predicate<? super T> predicate)get()ifPresent(Consumer<? super T> consumer)isPresent()map(Function<? super T,? extends U> mapper)orElse(T other)orElseGet(Supplier<? ex…

如何实现Action菜单

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

Swift 中的 StoreKit 测试

文章目录 前言创建一个 StoreKit Demo使用 SKTestSessionaskToBuyEnabled 属性总结前言 StoreKit 框架的第二次迭代是我在过去几年中应用程序中最重大的变化。最近版本的 StoreKit 框架已完全采用了 Swift 语言特性,如 async 和 await。本篇内容我们将讨论 StoreKitTest 框架…

AutoGen 两个agent讲相声

Lesson 1: Multi-Agent Conversation and Stand-up Comedy 第 1 课&#xff1a;多人对话和单口相声 Setup from utils import get_openai_api_key OPENAI_API_KEY get_openai_api_key() llm_config {"model": "gpt-3.5-turbo"}Define an AutoGen agent…

教育心理学期末考试重点

人本主义学习理论 人本主义主张&#xff0c;心理学应当把人作为一个整体来研究&#xff0c;而不是将人的心理肢解为不完整的几个部分&#xff0c;应该研究正常的人&#xff0c;而且更应该关注人的高级心理活动&#xff0c;如热情、信念、生命、尊严等内容。人本主义的学习理论…

线性代数|机器学习-P20鞍点和极值

文章目录 1 . 瑞利商的思考1.1 瑞利商的定义1.2 投影向量 2. 拉格朗日乘子法3. 鞍点4. 线性拟合4.1 范德蒙矩阵线性拟合4.2 python 代码4.3 范德蒙矩阵缺点 5. 均值和方差5.1 样本均值和方差5.2 总体期望 μ \mu μ,总体方差 σ 2 \sigma^2 σ2 1 . 瑞利商的思考 1.1 瑞利商…

算法金 | Transformer,一个神奇的算法模型!!

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 抱个拳&#xff0c;送个礼 在现代自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Transformer 模型的出现带来了革命性的变…

算法 —— 滑动窗口

目录 长度最小的子数组 无重复字符的最长子串 最大连续1的个数 将x减到0的最小操作数 找到字符串中所有字母异位词 长度最小的子数组 sum比target小就进窗口&#xff0c;sum比target大就出窗口&#xff0c;由于数组是正数&#xff0c;所以相加会使sum变大&#xff0c;相减…

云计算与生成式AI的技术盛宴!亚马逊云科技深圳 Community Day 社区活动流程抢先知道!

小李哥最近要给大家分享7月7日在深圳的即将举办的亚马逊云科技生成式AI社区活动Community Day &#xff0c;干货很多内容非常硬核&#xff0c;不仅有技术分享学习前沿AI技术&#xff0c;大家在现场还可以动手实践沉浸式体验大模型&#xff0c;另外参与现场活动还可以领取诸多精…

高优先线程

你开发的时候有么有遇到过一个问题&#xff1a;服务器的一个服务线程过几个小时断连一次&#xff0c;断连之后会马上重连这种情况。这是由于CPU负载较高,线程调度时将处理数据的线程挂起了一段时间导致的。 因此&#xff0c;我有考虑到把cpu的核心进行分散开来&#xff0c;就类…

关于发那科机器人系统升级方法

首先需要镜像备份和全备份&#xff0c;最好把机器人要到刻度线位置&#xff0c;零点位置 选择控制器启动&#xff0c;也可以按preevnext进入控制器模式

技术革新:如何用数据中台实现数字化转型

作为程序员&#xff0c;我们总是对技术如何改变企业运作充满好奇。今天&#xff0c;我们将深入探讨森马集团如何利用数据中台技术&#xff0c;实现从传统数据分析到数字化转型的华丽转身。 1. 技术背景&#xff1a;森马集团的数字化挑战 森马集团&#xff0c;一个在服饰行业占…

幻兽帕鲁服务器如何安装模组安装

由于模组多数为Window版本的&#xff0c;所以本教程以服务端为Window的作为演示&#xff08;Linux服务端的也是一样的操作&#xff09;百度莱卡云开服 如果你你是Linux版本的&#xff0c;请点击跳转切换服务端教程 接下来是本地安装模组包的方法&#xff08;服务器自带&#xf…