智能指针与句柄详解(一)

c++句柄,智能指针 指针间的区别 c++句柄,智能指针 指针间的区别,初学者可以下来了解了解 立即下载

前言:
智能指针与引用计数详解(一)中提到实现智能指针有两种方法,一种是引用计数,另一种就是句柄类实现。

什么是句柄类?
句柄类是用来存储和管理基类指针。指针所指对象的类型可以变化,它既可以指向基类类型对象又可以指向派生类型对象。用户通过句柄类访问继承层次的操作。因为句柄类使用指针执行操作,虚成员的行为将在运行时根据句柄实际绑定的对象的类型而变化。因此,句柄的用户可以获得动态行为但无须操心指针的管理。句柄本身也可以是某个C++对象,可以用来提供和指针一致的功能。

句柄类带来的好处:

  • 可以在实现中用运行时绑定而不是编译时绑定的方式来处理对象;
  • 可以对他人隐藏对象的实现。

包装了继承层次的句柄类有两个重要的设计因素:

  • 像对任何保存指针的类一样,必须确定对复制控制做些什么。包装了继承层次的句柄通常表现得像一个智能指针或者像一个值。
  • 句柄类决定句柄接口屏蔽还是不屏蔽继承层次,如果不屏蔽继承层次,用户必须了解和使用基本层次中的对象。

句柄分类:

  • 指针型句柄
  • 值类型句柄

指针型句柄
在句柄类中复制的是基类指针而不是对象,即多个指针共享一个对象。
实例:
定义一个名为Sales_item的指针型句柄类,表示Item_base层次。Sales_item的用户将像使用指针一样使用它:用户将Sales_item绑定到Item_base类型的对象并使用*和->操作符执行Item_base的操作:

定义句柄(Sales_item):
Sales_item类有三个构造函数:默认构造函数、复制构造函数和接受Item_base对象的构造函数。第三个构造函数将复制Item_base对象,并保证:只要Sales_item对象存在副本就存在。当复制Sales_item对象或给Sales_item对象赋值时,将复制指针而不是复制对象。像对其它指针型句柄类一样,将用引用计数来管理副本。
sales_item.h

#ifndef _Sales_item_h
#define _Sales_item_h

#include "item_base.h"

class Sales_item 
{
public:
    Sales_item();
    Sales_item(const Sales_item& sales_item);
    Sales_item(const Item_base& item_base);
    ~Sales_item();

    Sales_item& operator=(const Sales_item& sitem);
    const Item_base* operator->() const;
    const  Item_base& operator*() const; 

private:
    Item_base *m_item_base;
    int *m_useCount;

    void decr_use();
};
#endif

sales_item.cpp

#include "sales_item.h"
#include <iostream>
#include <exception>
using namespace std;

Sales_item::Sales_item()
    :m_item_base(NULL)
    ,m_useCount(new int(1))
{
    cout<<"Sales_item constructor"<<endl;
}

Sales_item::Sales_item(const Sales_item& sales_item)
    :m_item_base(sales_item.m_item_base)
    ,m_useCount(sales_item.m_useCount)
{
    cout<<"Sales_item copy constructor"<<endl;
    ++*m_useCount;
}

Sales_item::Sales_item(const Item_base& item_base)
    :m_item_base(item_base.clone())
    ,m_useCount(new int(1))
{
    cout<<"Sales_item item_base constructor m_useCount = "<<*m_useCount<<endl;
}

Sales_item& Sales_item::operator=(const Sales_item& sitem)
{
    bool isSame = this->m_item_base == sitem.m_item_base;
    cout<<"Sales_item assignment isSame = "<<isSame<<endl;
    if (!isSame) {
        ++*sitem.m_useCount;
        decr_use();
        m_item_base = sitem.m_item_base;
        m_useCount = sitem.m_useCount;
    }
    return *this;
}

Sales_item::~Sales_item()
{
    cout<<"Sales_item destruct"<<endl;
    decr_use();
}

const Item_base* Sales_item::operator->() const
{
    cout<<"Sales_item operator->"<<endl;
    if (m_item_base) {
        return m_item_base;
    }
    else throw ("unbound Sales_item");
}

const Item_base& Sales_item::operator*() const
{
    cout<<"Sales_item operator*"<<endl;
    if (m_item_base) {
        return *m_item_base;
    }
    else throw ("unbound Sales_item");
}

void Sales_item::decr_use()
{
    cout<<"Sales_item decr_use m_useCount = "<<*m_useCount<<endl;
    if (-- *m_useCount == 0) {
        delete m_item_base;
        delete m_useCount;
    }
}

相对于智能指针与引用计数详解(一)中的智能指针,主要有以下区别:
这里的句柄类中已经自己完成引用计数功能,不需要计数类;
接受Item_base对象的构造函数中运用了原型模式,主要原因是管理的基础指针涉及继承层次问题。

item_base.h

#ifndef _Item_base_h
#define _Item_base_h

class Item_base 
{
public:
    Item_base();
    virtual Item_base* clone() const;
    virtual ~Item_base();
    virtual  int net_price() const;
};

#endif

item_base.cpp

#include "item_base.h"
#include <iostream>

const int PRICE = 20;
using namespace std;


Item_base::Item_base()
{
    cout<<"Item_base constructor"<<endl;
}

Item_base* Item_base::clone() const
{
    cout<<"Item_base clone"<<endl;
    return new Item_base(*this);
}

Item_base::~Item_base()
{
    cout<<"Item_base destruct"<<endl;
}

int Item_base::net_price() const
{
    return PRICE;
}

bulk_item.h

#ifndef _Bulk_item_h
#define _Bulk_item_h

#include "item_base.h"

class Bulk_item : public Item_base
{
public:
    Bulk_item();
    virtual Bulk_item* clone() const;
    ~Bulk_item();
    virtual int net_price() const;
};
#endif

bulk_item.cpp

#include "bulk_item.h"
#include <iostream>

const int BULKPRICE = 30;
using namespace std;

Bulk_item::Bulk_item()
{
    cout<<"Bulk_item constructor"<<endl;
}

Bulk_item* Bulk_item::clone() const
{
    cout<<"Bulk_item clone"<<endl;
    return new Bulk_item(*this);
}

Bulk_item::~Bulk_item()
{
    cout<<"Bulk_item destruct"<<endl;
}

int Bulk_item::net_price() const
{
    return BULKPRICE;
}

main.cpp

    Item_base ib;
    Sales_item si(ib);
    Bulk_item bulki;
    Sales_item sbi(bulki);
    int siprice = si->net_price();       //正常输出20
    int price = sbi->net_price();       //正常输出30
    cout<<"siprice = "<<siprice<<endl;
    cout<<"price = "<<price<<endl;

运行结果:

// Item_base 类构造函数执行(对应代码:Item_base ib;)
Item_base constructor
// Sales_item 类接受Item_base 类构造函数执行(Sales_item si(ib);)
Item_base clone
Sales_item item_base constructor m_useCount = 1
// Bulk_item构造函数执行,根据继承关系,默认构造函数执行顺序是基类——>派生类
Item_base constructor
Bulk_item constructor
Bulk_item clone
Sales_item item_base constructor m_useCount = 1
// 句柄类重载“->”运算符,所以对应代码(si->),根据重载运算符逻辑,返回的是被管理的基础指针(Item_base ),所以能直接调用对应的成员函数。对于用户来说是透明的,感觉net_price函数是Sales_item 类的一样。
Sales_item operator->
Item_base net_price
// 对应代码(sbi->),由于多态原理,所以能够输出各自正确的值。
Sales_item operator->
Bulk_item net_price
siprice = 20
price = 30
//程序执行完毕,会回收对象(sbi),对应的是decr_use函数(delete m_item_base;)
Sales_item destruct
Sales_item decr_use m_useCount = 1
Bulk_item destruct        // 由于delete m_item_base对应的m_item_base指向的对象是Bulk_item
Item_base destruct
//回收bulki,析构函数是虚函数,所以执行顺序是派生类——>基类
Bulk_item destruct
Item_base destruct
//回收si
Sales_item destruct
Sales_item decr_use m_useCount = 1
Item_base destruct
//回收ib
Item_base destruct

小结:
句柄是C++中的一种普遍使用的实现技巧。它们赋予了类设计者足够的弹性来处理不定大小的实现,减少编译期的依赖,阻止他人获得类的实现细节,以及为同一个抽象数据类型提供不同的实现。在C++中,动态绑定仅在通过引用或指针调用时才能应用于声明为虚的函数。C++程序定义继承层次接口的句柄类很常见,这些类分配并管理指向继承层次中对象的指针,因此能够使用户代码在无须处理指针的情况下获得动态行为。

扩展:
上述的例子介绍了指针型句柄,另外还有值型句柄,同时为了适配可以用模板来实现。

《AI编程实战:深度学习模型改进与系统部署》,改进专栏目录和介绍 专深度学习相关项目都写在本专栏,《一次订阅解锁全部,都有源码,永久观看》,包括车牌识别、股票预测、人脸识别、风格迁移、图像修复、图像超分辨重建、图像分割等任务,Web/PyQt系统实现。引入Transformer、Swin Transformer、DenseNet、ViT、ConvNeXt等算法实战,提供卷积改进,魔改对比实验,模型剪枝,模型蒸馏,模型量化,全网独家整合改进专栏,为不同领域的同学发表论文提供了大力支持。 阅读详情

相关推荐

ABAP传输自定义IDOC实例

首先确定出站方和入站方,本例中我使用150作为发送方将200作为接收方。 发送端系统配置 进入tcode-SALE,点击定义逻辑系统,这里我定义D01CLNT150为发送端, D01CLNT200为接收端 2,将逻辑系统分配给对应的client 3,进入tcode-WE31,创建IDOC开发段(segment)这里可以按照实际需求创建想要传输的结构,为求简单我创建了ZKNA1并选取了几个客户主数据的字段作为示例 4,进入tcode-WE30,创建Idoc Ty...

Nathan的博客 4076

句柄与指针的区别

一文带你了解,指针、句柄、上下文、Java对象管理框架Spring

qq_45672232的博客 3986

【Python爬虫】爬取企业专利信息

本来是个美好的周末的,但是周五晚上领导给了一个公司名称的Excel,让把这些公司的专利信息爬取下来。本文记录了爬取企业专利信息的心酸过程。码字不易,喜欢请点赞!!! 一、找寻目标网页 在接到这个任务之后,我的内心是拒绝的。但是又不能不干。因此首先我需要先找到有公司专利信息的地方。在一番查找和问了问朋友之后,我知道中国专利网、国家知识产权网、Incopat、天眼查、企查查这些网站上面都有企业的专利...

Asher117的博客 2万+

引用、指针和句柄的区别

句柄是一种特殊的智能指针 。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。句柄与普通指针的区别在于,指针包含的是引用对象的内存地址,而句柄则是由...

bigzql的博客 2万+

使用openair包分析气象数据

气象数据通常是有规律的时间序列,分析气象数据时需要对空气质量测量、气象数据和扩散模型输出进行分析。openair 是用于分析空气质量数据或更广泛的大气成分数据的R软件包。该软件包广泛应用于学术界、公共和私营部门。该项目最初由英国自然环境研究委员会(NERC)资助,并由英国环境部(Defra)提供额外资金。

Christina 2518

属性基加密(Attribute-based Encryption, ABE)

KP-ABE中,用户的密钥定义了访问策略,密文的属性与策略进行匹配。CP-ABE中,密文定义了访问策略,用户的属性与策略进行匹配。

2201_75392924的博客 1830

句柄和指针

学习的过程中不太理解句柄是什么,和指针有什么区别,看了一个视频(指针和句柄),感觉大致理解了一点,记录一下,在实际应用中再有理解会继续补充。

cdbxxx的博客 1658

CODESYS数据处理合集(高低字节/ 字/浮点数/位)

VAR_INPUT//字节0//字节1END_VARVAREND_VAR。

RXXW_Dor的博客 352

指针和句柄的区别和联系

指针和句柄的区别和联系

ttod的博客 895

《QGIS快速入门与应用基础》079:KML/KMZ格式:Google Earth兼容

KML/KMZ是专为地理可视化设计的空间数据格式,原生兼容Google Earth,支持点线面要素标注与多媒体集成。KML为XML文本格式,KMZ是其压缩版本。该格式优势在于可视化表现力强、跨平台共享便捷,适合地理标注、路线分享等场景,但存在属性支持弱、大数据量处理效率低等局限。QGIS中可便捷加载和导出KML/KMZ数据,需注意编码设为UTF-8、勾选"导出样式"以保留可视化效果。建议中小规模标注数据使用KMZ格式,确保关联资源完整,提升共享效率。

LuckyHanMo的博客 765

Qt C++ HTTP 调用通义千问大模型 X 学术论文润色工具(SCI 格式适配)

请求地址:`https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation`;| Windows | 打包时携带 `Qt6Network.dll`/`libcrypto-1_1-x64.dll` 等依赖;| Linux | 安装 `libssl-dev` 和 `libcurl4-openssl-dev`;| API 调用失败 | 检查 API-KEY 是否有效;

寒寒豆豆软件公司的博客 104

指针,句柄和引用的区别

没得写

weixin_39765162的博客 964

SAP 批量修改 工艺路线 和 BOM

1、在运维的过程中经常会遇到用户需要批量更改组件,或者是批量更改数量,还是组件里面的一些标识,当处理这些批量数据处理的业务时,BOM的批量更改一个想到的就是CS20,但是CS20当BOM需要替换的时候就不是很适用。当前工作区域:选择 SAP_ITEM 对BOM行项目进行变更,工艺路线也是可以批量更改的,根据实际的业务进行选择,我这里选择的就是BOM的组件变更。5、本博客将使用新的一种方式进行BOM的批量变更,标准的事务代码:CEWB对BOM进行批量更改。3、使用LSMW的方式进行BOM的批量更改。

我小时候很黑的博客 4092

句柄类的对象与智能指针

  句柄类, 来自于C++ 沉思录的概念   百度百科:   句柄(handle)是C++程序设计中经常提及的一个术语,它并不是一种具体的、固定不变的数据类型或实体,而是代表了程序设计中的一个广义的概念,句柄一般是指获取另一个对象的方法 —— 一个广义的指针,它的具体形式可能是一个整数、一个对象或就是一个真实的指针,而它的目的就是建立起与被访问对象之间的唯一的联系   句柄(ha...

金色的省略号 774

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【C++重载操作符与转换】句柄类与继承

在 C++ 面向对象编程中,句柄类 (Handle Class) 是一种强大的设计模式,它允许我们以统一的接口操作不同类型的对象,同时隐藏对象的具体实现细节。结合继承和多态机制,句柄类可以实现灵活的对象管理,尤其适用于需要处理多种派生类对象的场景。

byte轻骑兵的技术小窝 1856

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

句柄是什么

句柄(Handle)是一个是用来标识对象或者项目的标识符,可以用来描述窗体、文件等,值得注意的是句柄不能是常量。 Windows之所以要设立句柄,根本上源于内存管理机制的问题,即虚拟地址。简而言之数据的地址需要变动,变动以后就需要有人来记录、管理变动,因此系统用句柄来记载数据地址的变更。在程序设计中,句柄是一种特殊的智能指针,当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。 Windows是一个以虚拟内存为基础的操作系统,很多时候,进程的代码和数据并不全部装入内存

顺其自然~专栏 7506

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

智能指针与引用计数详解(一)

前言 在C++项目开发中,有时候会遇到悬垂指针的问题,其中提供的解决方案推荐使用智能指针。 在《C++Primer》书13.5章 提到了该技术的具体使用场景和实现。通过反复阅读和代码测试终于了解其中的思想,下面谈谈自己的理解,如果发现有什么问题,请大家批评指正。 什么是智能指针? 智能指针其实就是一个类,除了增加了一些功能外,其因为跟跟普通指针一样。通常情况,new一个对象会申请一块内存,复制或者...

yj_android_develop的博客 7609

智能指针与句柄详解(二)

前言 智能指针与句柄详解(一)中讲了句柄类的实现,本章将用C++模板来实现句柄类。

yj_android_develop的博客 250

C++智能指针详解与应用

详细介绍了C++智能指针如何解决内存泄漏问题,以及具体实现

qq_74319491的博客 956

智能指针之句柄类

对于上一篇提到的方法,可以不用引入辅助类,可以直接把指针封装起来。然后,重载操作符,定义为一个指针的行为,使得可以像使用指针一样使用它。这种方法叫做句柄类,查下了资料,对这个的解释是存储指向动态分配对象指针的类。可以在适当的时间自动删除指向的对象,同时,它的行为也像一个指针。 同样的先上一张图。 1.定义一个SmartPtr对象P1,传入实际指针对象,调用构造函数,初始化计数为1; 2.定义

千里之行始于足下 864

c++智能指针,句柄类

智能指针 某些时候会在一个类里定义一个指向另一个类的指针,如此多个对象可通过指针访问一个共享对象,但如果指向的对象被删除,则可能产生一批悬垂指针。解决这个问题又实现共享可使用智能指针类。 动态分配一个共享对象并把它的地址传给智能指针类的对象,类的用户可通过指针访问共享对象,但不能删除其指针。删除指针的行为由智能指针类管理,在撤销最后一个智能指针类的对象时删除指向共享对象的指针。 ...

157

智能指针的实现及原理 + Good ! 句柄类

C++程序设计的一种常用技术——智能指针(smart pointer),主要内容包括引用计数(reference count)和句柄类(handle class)。 当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。    智能指针(smart pointer)的

so true_interview / 1413

智能指针是一种类,别名称为句柄类

引子:智能指针是不是指针? 看C++ primer时,一直心存这样的疑问? 而在面向对象里面提及到一种概念-智能指针,而往往同学会出现以下的问题 【问题】   智能指针是不是一种指针?   stl里面的智能指针是什么? 【回答】   智能指针是一种类,别名称为句柄类。而这种类型恰恰是《设计模式》中的代理模式、适配器模式(这两种模式以后会在MyBlo

xinghexiyue的专栏 1165

C++句柄类(智能指针)小结

句柄类作用主要有两个: 支持面向对象编程,实现多态性质;减少头文件的编译依赖关系,让文件间的编译更加独立。 1.句柄类存储和管理基类指针,指针既可以指向基类类型对象又可以指向派生类型对象。用户通过句柄类访问继承层次的操作,用户可以获得动态行为,同时能够确保自动正确的销毁动态分配的对象,防止内存泄露。《C++ Primer》 15.7 节中用购物篮的例子说明了C++不能通过对

summer 3350

【一天一个C++小知识】005. C++中的句柄类(智能指针)

  句柄类作用主要有两个,一是支持面向对象编程,实现多态性质;二是减少头文件的编译依赖关系,让文件间的编译更加独立。   句柄类存储和管理基类指针,指针既可以指向基类类型对象又可以指向派生类型对象。用户通过句柄类访问继承层次的操作,用户可以获得动态行为,同时能够确保自动正确的销毁动态分配的对象,防止内存泄露。C++不能通过对象支持多态,而必须使用指针或引用。若保存基类的对象:派生类对象只有基类部分保存下来,而派生类部分被切掉;如果保存派生类的对象,基类对象无法有效转换为派生类对象。   在Effective

kevin_zhao_zl的博客 753

句柄无效是什么意思_引用、指针和句柄的区别

句柄是一种特殊的智能指针 。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。句柄与普通指针的区别在于,指针包含的是引用对象的内存地址,而句柄则是由系统所管理的引用标识,该标识可以被系统重新定位到一个内存地址上。这种间接访问对象的模式增强了系统对引用对象的控制。句柄就是个数字,一般和当前系统下的整数的位数一样,比如32bit系统下就是4个字节。 ...

weixin_29143339的博客 2421
上一篇: 智能指针与引用计数详解(二)
下一篇: C++模板与泛型编程
OODeveloper
博客等级 码龄12年 43粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值