在STL中处理对象指针

STL四种智能指针浅析 我们知道,在C++中没有像Java那样的自动回收垃圾机制,,系统只会清理栈上由系统管理的资源,在类中若有对堆资源的申请,不进行手动释放资源就会导致内存泄漏问题,在学习了类和类模板之后,我们发现在类中有析构函数来进行资源释放功能,并且析构函数还支持加入程序员自身的操作,那么将指针托管给对象来实现可以做到程序员手动申请资源,让系统自动回收资源的效果,Boost库就提供了这样的智能指针来实现C++的自动... 阅读详情

在STL中处理对象指针

众所周知,STL的容器类是针对对象来进行存储管理的。虽然没有明确的限制不能在STL的容
器类中包含指针,STL也不在乎您存放在容器中的对象还是指针。但仔细考虑STL的初衷,
在容器类中使用指针是明显不合时宜的。
CKER的意思是您应该尽可能的直接将对象本身而不是将对象的指针放置在STL容器类中。直接
在容器中存放指针一个最大的副作用就是可能导致内存泄漏。这个问题在char *类型上有突出
的体现。
但某些时候,直接使用对象指针有明显的好处,这些情况大致可以概括为如下的几个方面:
1. 当对象十分庞大时,频繁的拷贝复制所带来的系统资源消耗十分昂贵。
2. 当您需要将同一个对象存放到多个容器中,这种情况应该不是很少见的。
3. 当您需要在同一个容器中存放由同一个父类派生而来的多个派生类对象。这也很常见。
事实上,CKER这个星期所开发的计算程序中,正需要面对第三种情况。考虑使用STL的种种好处。
CKER决定引入STL的list容器。

本来,使用BCB的TList对象,也可以实现同样的目的。
但
TLsit类在对象指针的个数超过5000个时,效率会有明显的下降。
TList类不是类型安全的,它根本不在乎引入的对象指针是何种类型的。
引入TList类就意味着要包含VCL.h头文件,这对我的计算模块的可移植性实在不是一件好事。

cker做了决定之后,面临两个与stl有关的问题。
第一个问题就是上面提到的如何在STL中处理对象的指针。
CKER的解决之道是创建一个封装指针的类。
代码如下:

// 定义一个用于STL容器的指针封装类
// 因为使用STL不宜直接向容器中添加指针。
////////////////////////////////////////////////////////////////////////////////
class PtrWrapper
{
private:
    X* px;//指向类X的指针

public:
    file://构造及拷贝构造函数
    PtrWrapper(X* x = 0) : px(x) {}
    PtrWrapper(const PtrWrapper& pw) : px(pw.px) {}
    file://析构函数
    ~PtrWrapper() {}
    PtrWrapper& operator= (const PtrWrapper& pw) { px = xw.px; }

    file://重载运算符()返回对象X的指针
    const X* operator() () const { return px; }
    X* operator() () { return px; }
};

file://重载逻辑运算符 == , < , >
bool operator== (const PtrWrapper& pw1, const PtrWrapper& pw2) {
    return (pw1.operator()() && pw2.operator()()) ? *pw1() == *pw2() : false;
}

bool operator< (const PtrWrapper& pw1, const PtrWrapper& pw2) {
    return (pw1() && pw2()) ? *pw1() < *pw2() : false;
}

bool operator> (const PtrWrapper& pw1, const PtrWrapper& pw2) {
    return (pw1() && pw2()) ? !(*pw1() < *pw2()) : false;
}


上述代码封装了一个指针。经过类PtrWrapper的封装后,您就没有必要直接使用指针了。
STL容器接触的是真正的对象,只不过这个对象封装了一个特定类型的指针。
下面举例说明PtrWrapper的使用。


// 假设您需要将指向类X的对象的指针放入STL容器。
//
class X
{
private:
    int I;

public:
    file://构造函数,拷贝构造函数,析构函数
    X(int i) : I(i) {}
    X(const X& x) : I(x.I) {}
    ~X() {}
    file://重载运算符= ,()
    X& operator= (const X& x) { I = x.I; }

    int operator()() const { return I; }
};
file://重载逻辑运算符
bool operator== (const X& x1, const X& x2) {
    return x1() == x2();
}

bool operator< (const X& x1, const X& x2) {
    return x1() < x2();
}

 


file://下面是示例主程序
int main(int, char*[]) {
    PtrWrapper bucket[5];
    for(int i = 0; i < 5; ++i) {
        bucket[i] = PtrWrapper(new X(i * i));
    }
    random_shuffle(bucket, bucket + 5);

    list<PtrWrapper> list1;
    copy(bucket, bucket + 5,
        back_insert_iterator<list<PtrWrapper> > (list1)
    );

    cout << "List of PtrWrapper: (";
    for_each(list1.begin(), list1.end(), print);
    cout << ")" << endl;

    set<PtrWrapper, greater<PtrWrapper> > set1;
    copy(list1.begin(), list1.end(),
        insert_iterator<set<PtrWrapper, greater<PtrWrapper> > >
            (set1, set1.begin())
    );

    cout << "Set of PtrWrapper : [";
    for_each(set1.begin(), set1.end(), print);
    cout << "]" << endl;

   deque<PtrWrapper> deque1;
    copy(list1.begin(), list1.end(),
        back_insert_iterator<deque<PtrWrapper> > (deque1)
    );

    cout << "Deque of PtrWrapper : (";
    for_each(deque1.begin(), deque1.end(), print);
    cout << ")" << endl;

    return 0;
}

还有一个问题是如何在STL容器种存放派生类对象,下次讨论。

注:文中的代码原型来自于Internet,可惜网址没留下来。CKER整理之后贴出来,姑且妄称原创了。

您可以随意复制、分发、下载此文档。但未经本人同意,您不可以截取、改动本文片断,或用本文谋取任何形式的利益。
有任何意见和建议请mailto:cker@sina.com

当使用STL容器去存放数据时,是存放对象合适,还是存放对象指针(对象地址)合适? 当我们使用STL容器去存放数据时,是存放对象合适,还是存放对象指针(对象地址)合适? 阅读详情

相关推荐

C++STL中智能指针介绍

介绍stl中三种智能指针,对于学习STL很有帮助.上次面试就被问到了。

STL 智能指针

转自: https://blog.youkuaiyun.com/k346k346/article/details/81478223 STL一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr和weak_ptr,auto_ptr是C++98提供的解决方案,C+11已将其摒弃,并提出了unique_ptr作为auto_ptr替代方案。虽然auto_ptr已被摒弃...

weixin_30843605的博客 270

Oracle-OGG trail 文件大小引起的进程异常 OGG-01172

监控OGG目标端进程,其中一个进程异常,状态为 ABENDED,start repa 执行失败。进入OGG报告目录检查运行报告 2015-04-20 09:38:36 ERROR OGG-01172 Discard file (/ogg/oggrm/11.2/dirdat/repa.dsc) exceeded max bytes (2000000000). 总结处理方法,从根本上解决问题。

xdyzgjy的专栏 7956

C++ STL 四种智能指针

auto_ptrunique_ptrshared_ptrweak_ptrauto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述。shared_ptr 和 weak_ptr 则是 C+11 从准标准库 Boost 中引入的两种智能指针。

Doublelv 的博客专栏。 7万+

计算文本相似度的常用算法

NLP、数据挖掘领域中,文本分析是一个很重要的领域,这有助于我们去让计算机理解语言的作用和使用。文本分析是数据挖掘的重要手段,利用文本分析,我们将很快的读取到一本书、一篇文章、一段话中的关键词和核心思想,而文本相似度就是我们用来剔除无用信息或者重复信息的重要手段,让计算机去找文本中的不同。 在生活中,信息检索、数据挖掘、机器翻译、文档复制检测等领域都应用到“文本相似度”。文本不仅仅是文字,文本相似度的应用更广,除了文字的匹配,还可以是图片、音频等,因为它们的实质都是在计算机中都是以二进制的方式存在的。相.

氧小氢的博客 2万+

Centos7安装NVIDIA驱动并在docker容器中使用GPU

Centos7安装NVIDIA驱动并在docker容器中使用GPU

运维giao的博客 2084

STL容器里存放对象还是指针

一.问题的引出: 容器可以存放对象,可以存放指针,这里要谈的是两者的使用问题。就是什么时候存放对象更好,什么时候存放指针更好?   二.问题的分析过程: 1. 首先说下stl容器的工作方式   对于内建类型(int float char等),容器的工作方式是纯粹的位拷贝,这里没有什么需要多说的。 对于自定义的对象,容器容纳了对象(比如通过insert或pu

zhongkeli的专栏 1816

JS+H5打字练习器

实现功能 1.导入.TXT文件到打字练习内容(部分浏览器可能出于安全问题限制了这一步操作) 2.输入文本到打字练习内(弹出输入框,将要练习的内容输入至输入框) 3. 开始练习,并根据正误在打字练习内容文本上修改颜色(某个字正确显示绿色,某个字错误,显示红色,某个字没有打显示灰色) 4.开始练习、结束练习,全部输入完成后自动结束练习,也可提前手动结束练习,结束练习后弹窗用显示时和正确率。(区别在于一个全部输入完成且全部正确,一个提前结束无其他条件) 效果图 分析 HTML 结构解析 根元素:<!DO

w11111xxxl的博客 1413

c++面试题(基础篇)

● STL标准模板库 (1)vector的底层存储机制:vector是一个动态数组,里面有一个指针指向一片连续的内存,当空间不够时就用动态重新分配 ,一般是当前大小的两倍,然后把原来的数据拷贝过去,释放原来的地址空间,当删除里面的数据时,它的存储空间是不释放的,仅仅是清空了里面的数据。 (2)list的底层存储机制:list是以结点为单位存放数据,数据在内存中不一定连续。 (3)vector

周春岳的程序人生 822

各种逻辑漏洞

注册:短信轰炸验证码安全问题密码爆破邮箱轰炸用户任意注册、批量注册用户名枚举XSS(有框的地方就可以尝试插XSS)登录:短信轰炸、验证码安全问题、密码爆破、邮箱轰炸SQL注入撞库抓包把password字段修改为空值发送认证凭证替换、比如返回的数据包中包含账号,修改账号就能登录到其他账号Cookie仿冒修改返回包的相关数据,可能会登陆到其他的用户找回密码:短信邮箱轰炸、短信邮箱劫持重置任意用户账户密码、验证码手机用户未统一验证直接跳过验证步骤。

shirlly_的博客 2093

<PLC><工控>汇川Easy521PLC与压力传感器485通讯实例

有些PLC在进行串口通讯时,配置完串口参数后,还需要自己编程序来读写,但本例中汇川Easy521配置完成后,想要读取从站什么数据,只需要在“COM0 Modbus配置窗口”配置即可。可以同时配置多个从站。在配置窗口的右侧点击新增按钮,就会自动生成一条从站的配置,默认从站站号为“1”,触发方式是“循环”,功能码是03(读寄存器),从站寄存器地址为0,长度为“1”,映射地址需要自己添加。因为我们是将PLC设置为Modbus主站,所以压力传感器就是从站,我们的需求时PLC从这些从站传感器中读取数据,比如压力值。

用沸腾的热血,支付我们的人生吧! 6457

c语言对象指针,c语言入门之在STL中处理对象指针

众所周知,STL的容器类是针对对象来进行存储管理的。虽然没有明确的限制不能在STL的容器类中包含指针,STL也不在乎您存放在容器中的对象还是指针。但仔细考虑STL的初衷,在容器类中使用指针是明显不合时宜的。CKER的意思是您应该尽可能的直接将对象本身而不是将对象的指针放置在STL容器类中。直接在容器中存放指针一个最大的副作用就是可能导致内存泄漏。这个问题在char *类型上有突出的体现。但某些时候...

weixin_39679678的博客 165

路径规划 | 图解RRT*算法(附ROS C++/Python/Matlab仿真)

RRT*算法针对传统RRT算法进行了渐进最优改进,在添加节点到搜索树的过程中进行重连选择。本文图解RRT*算法原理,并采用ROS C++、Python、Matlab三种语言实现算法,加深理解

FRIGIDWINTER的博客 9405

STL三大组件

各位读者,由于本篇幅度过长,为了避免影响阅读体验,下面我就大概概括了整理了《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取![外链图片转存中…(img-YlktDLMx-1712223428094)]《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

2401_83915900的博客 901

08-StarRocks性能调优FAQ

StarRocks性能调优摘要 本文提供了StarRocks数据库性能调优的常见问题解答,涵盖查询优化、索引设计、分区策略和系统配置等关键方面。主要内容包括:查询优化技巧(使用EXPLAIN分析、避免全表扫描、优化JOIN和聚合查询);索引选择与维护建议(高频查询列索引、复合索引);分区策略设计(时间分区、范围分区)及其管理方法;以及系统内存配置优化(JVM参数调整、查询内存限制设置)。这些优化措施可显著提升StarRocks的查询性能和系统效率。

欢迎来到我的博客,一起探索代码里的世界! 541

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++-STL(9)-unordered_map-自定义类型(2)key-自定义对象指针-实例源码

C++-STL(8)-unordered_map讲的自定义对象中的成员变量是基础数据类型。 本篇实现的是成员变量是自定义对象,key值为自定义对象指针。注意点:1.创建:重载=,重载<,重载 哈希函数 2.删除时 要delete 和置空。 上代码: class nodemap { public: int m_value; //基础数据类...

aggie4628的专栏 881

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

vector的clear操作的内部过程

最近在论坛看到一个提问帖子,问题是vector中存储了对象的指针,调用clear后这些指针如何删除? [cpp] view plaincopy class Test   {   public:       Test() {}       ~Test() { cout "Test des"  };       int main()  

youwuwei2012的专栏 798

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

c++,stl,map容器,构造,元素插入,遍历,修改键值时的注意点

c++,stl,map容器,构造,元素插入,修改,遍历 map容器是相当常用的stl容器,它的元素插入有四种方法,基于insert的三种和下标赋值一种,同时map本身的性质就是没有重复键,所以会出现插入失败的情况,map容器本身也提供了键入结果检测的方法。 元素类型: map中的元素是成对出现的,其每个元素都是一个键和其对应的值组合成的pair型数据,搜索时使用find拥有和下标访问相同的时间复杂度。 构造: 首先构造一个map,<>中前面一个是键,后面一个是值,map中不能插入相同键的数据元素

ganfanren00001的博客 1994

java中的fun,STL中mem_fun和mem_fun_ref的用法及区别

怎么对容器中的所有对象都进行同一个操作?我们可能首先想到的是用循环来实现。比如有如下的一个类:class ClxECS{public:int DoSomething() {cout << "Output from method DoSomething!" << endl; // 这里以输出一句话来代替具体的操作return 0;};};现在定义如下一个vector:vect...

weixin_34262786的博客 143

vector<int>::iterator和vector<int*>::iterator以及vector<int>*的不同

为什么80%的码农都做不了架构师?>>> ...

weixin_34417635的博客 368

《STL源码剖析》学习--traits

在本书迭代器一节提到了Traits编程技法,将其誉为stl源码门匙,在《C++编程思想》一书中,将其列为模板编程中的习语“特征”,这里进行总结。 traits技术 也往往和迭代器一起使用。 1、理解概念 在《C++编程思想》一书中,特征模板技术,定义为一种将与某种类型相关联的所有声明绑定在一起的方法,可以以一种灵活的方法从语境中将类型和值进行“混合和匹配”,同时又使得代码灵活易读且易于维护。

KUAILE123的专栏 1244

知乎C++问题整理

如何平衡性能,合理选择C++STL集装箱? ANSER: 首先要搞清楚,假设STL问题,那么问题出在哪里? STL能够简单地觉得就是算法+数据结构,全部容器的算法选择和实现都是经过精心设计和严格測试的,几个主流STL实现都不会有大问题。 性能问题通常都出在内存数据操作上,内存操作有三种。内存读取、内存复制和内存分配。 所以选择合适容器的根据就是要尽量降低内存操作尤其是...

weixin_33676492的博客 156
上一篇: Bjarne Stroustrup的 C++ 风格与技术常见问题与答案 (节译一)
下一篇: 取得系统中网卡MAC地址的三种方法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值