news 2026/6/9 19:47:49

c语言对话-1.auto_ptr再回忆

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c语言对话-1.auto_ptr再回忆

toulouse 翻译

我刚刚在昨天遇到珍妮,就在人员中转站,现在已经远远在我们脚下了。“我会永远记住我的第一个工作,”在乘务员检查完我们的安全带后,我对她说。

“想起了什么”

“项目组高级程序员,”我微笑着说,陷入了回忆中。“她是个古怪的家伙,我们都叫她做Guru。领导不喜欢把新来的程序员分到她的组里;我是当年招聘的四个人中唯一坚持到试用期结束的。”

珍妮扭过头刚准备问一个问题,这时钟声响起,隆隆的加速声响彻整个机舱,我们的谈话因此中断了好几分钟,等这截推进器快烧完时,我们已飞离轨道,我给她讲述了工作第二天发生的故事。

我们用早期的C++语言编程。工作的第二天中午,厌烦了读职工手册,于是我写了一个工具类,里面包含一个原始指针作为成员变量:

#include "xStruct.h" // definition of struct X

class xWrapper

{

X* xItem;

public:

xWrapper() : xItem(new X) { }

~xWrapper() { delete xItem; }

void dump() { /* dumps xItem to cout */ }

};

当然了,使用这个类的程序由于内存问题总是时不时的崩溃,因为我违反三个重要设计原则之一:任何时候,只要你提供了析构函数、拷贝构造函数或赋值运算符中的一个,你通常需要三个都提供。([1]) “所以,”我自言自语道,“我必须自己处理拷贝和赋值问题。简单地...auto_ptr有拷贝构造函数和赋值运算符,我可以拿过来用一下。”(你知道早期C++程序库中的auto_ptr,是吗?)

既然auto_ptr自动删除它所指向的对象,我只需要改变xItem的类型,移去析构函数中的delete语句-auto_ptr会处理其他的事情,对吗?

Class xWrapper

{

auto_ptr<X> xItem;

public:

xWrapper() : xItem(new X) { }

void dump() { /* dumps xItem to cout */ }

};

不幸的是,程序仍要崩溃,这次是由于它试图对空指针进行提领操作。我对这个问题苦苦思索了半个小时,这时Guru碰巧从我这里路过,像芦柴棒一样瘦瘦的她一只手里捧着厚厚的一本打开的书。 她来得――我的意思是她来得太不是时候了,真是怕什么来什么,实际上,这简直称得上诡异了。

“哦,你在看什么?”我指着书问,想让她的注意力从我的屏幕挪开,同时也希望着她能离开。

Guru眨了眨眼睛。“Josuttis的书,”她边温和地说着,边做了个标记并合上书。“年轻人,你写了些什么啊?”

“我在写这个wrapper class时遇到了问题,”我承认道,“我使用了auto_ptr成员,但是在测试时,不知为什么它的指针重置为null。”

“把你的代码给我看一下,”Guru说。我把屏幕转向她。“所有权,”仅仅扫了一眼,她立刻说,

这回轮到我眨眼睛了。

“所有权,孩子;你的问题是所有权语义学。一臣不事二主,没有指针可以同时给两个auto_ptr使用。”

她的话虽然很怪,却使我意识到了自己的错误。“哦,是的,”我答道。“当你拷贝一个auto_ptr的时候,原来的那个放弃了所有权,重置为null。Xwrapper的拷贝构造函数使用了那个缺省的行为,所以原来xWrapper对象的auto_ptr被重置,于是我存取它的时候,实际上是在提领一个null指针。”

“对的,”Guru说。“你能使用标准里已有的代码,这很好,不过使用的时候要小心。对于xWrapper来说,你还是必须自己写拷贝构造函数和赋值运算符。”

“但是,我没法用auto_ptr的拷贝构造函数和赋值运算符来实现他们啊,因为auto_ptr自己的版本无法正确的……-哦。有办法了。我可以用auto_ptr的提领运算符访问其拥有的对象。”我很快写下了下面的两个函数:

XWrapper::xWrapper(const xWrapper& other)

: xItem(new X(*other.xItem))

{ }

xWrapper& xWrapper::operator=(const xWrapper &other)

{

*xItem = *other.xItem;

}

“嗨,cool。”我喜欢这个实现,“我甚至不需要在赋值运算符里检查自我赋值。”

“很好。”

我应该就此打住,闭紧嘴巴,可惜我当时正得意着呢:“使用auto_ptr很容易出错。如果在我实际上并不想发生所有权转移时,它可以告诉我它将试图转移所有权,那有多好啊……”。”

“冷静一下!”Guru打断了我。“这不是auto_ptr的错。如果你想达到这个效果,你应该明确地说明你不想auto_ptr被拷贝。”

“但是怎么去做呢?这是不可能的。”

“可能的。记住const修饰符的使用。声明一个auto_ptr不可变的方法是使它成为const。假如你让成员成为一个const,编译器就不能不声不响地产生xWrapper对象的一个拷贝。或者,你可以使用一个也许叫strict_auto_ptr的修正版本,这样编译器就不会错误地拷贝和赋值xWrapper。当然,在这种情况下,让它成为const比较简单和有效率。” ([2])

她离开的时候又重新打开Josuttis的书继续看了起来,边走边心不在焉地和我说这话。她和她的声音慢慢地远去:“要注意的是,我的孩子...auto_ptr是一个有用的工具,但是就象你刚才发现的那样,它不是万能的。好好琢磨Josuttis chapter 4.[3],永远不要在标准程序库的容器中用auto_ptr,如vector<auto_ptr>,因为auto_ptr的拷贝和赋值不能达到标准的要求。此外,永远不要用auto_ptr指向对象数组,因为auto_ptr的析构函数用non-array delete删除所拥有的对象;对于对象数组来说,可以用一个vector。程序库...”

这时她转了个弯,消失了。这只是我工作的第二天;我告诉自己,不能空闲下来,我应该不断地学习,前面的路还很长!

“不可思议,”珍妮说,喝着咖啡,此时飞船已飞离了泰兰的交通控制区域,并继续加速,“那么,你离开了吗?”

“她...我不确定为什么,”我坦白承认,“这种事发生了好几次。我也想和其他人那样在试用期离开,尽管他可能对我有好的影响。你曾经和这样的怪人工作过吗?”

“嗯,我想也有一些。”

这不是最后一次我和珍妮谈论Guru或其他更令人高兴的事。

[注释]

1. M. Cline, G. Lomow, and M. Girou. C++ FAQs, 2nd ed. (Addison-Wesley, 1999).

2. Ibid., FAQ 30.12, pages 426-8.

3. N. Josuttis, The C++ Standard Library (Addison-Wesley, 1999).

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 11:52:45

2026年趋势:AI驱动测试即服务(TaaS)兴起

技术融合下的测试新纪元 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;软件测试行业正经历一场深刻变革。2026年&#xff0c;AI驱动的测试即服务&#xff08;TaaS&#xff09;模式将全面兴起&#xff0c;彻底颠覆传统测试流程。这一趋势源于AI在自然语言…

作者头像 李华
网站建设 2026/6/6 11:51:39

AI工具集成实战教程:赋能测试工程师的智能化转型

随着生成式AI&#xff08;Generative AI&#xff09;的爆发式发展&#xff0c;软件测试领域正经历从自动化到智能化的革命性变革。大型语言模型&#xff08;LLM&#xff09;和生成对抗网络&#xff08;GAN&#xff09;等技术&#xff0c;已深度融入测试用例生成、缺陷预测、脚本…

作者头像 李华
网站建设 2026/6/6 11:53:14

降维打击!南医大最新研究:多指标+多库联合新思路眼前一亮

源自风暴统计网&#xff1a;一键统计分析与绘图的AI网站 引言多数据库&#xff0b;多指标&#xff01;今天这篇中国学者的文章的工作量真的让人惊叹&#xff01;用多数据库数据进行检验&#xff0c;重复的操作&#xff0c;结果却足够权威&#xff01;也是一种发文的好思路&…

作者头像 李华
网站建设 2026/6/6 12:39:44

IQuest-Coder-V1-40B-Instruct代码实例:Python调用完整指南

IQuest-Coder-V1-40B-Instruct代码实例&#xff1a;Python调用完整指南 1. 这个模型到底能帮你写什么代码&#xff1f; 你可能已经见过不少代码大模型&#xff0c;但IQuest-Coder-V1-40B-Instruct有点不一样——它不是泛泛而谈的“会写Python”&#xff0c;而是真正懂软件工程…

作者头像 李华
网站建设 2026/6/6 16:07:24

CHIPSTAR智浦欣 CS8122S CS8138S SOP-8 线性稳压器

特性 5伏士2%稳压输出 低压差电压(0.6V0.5A) 750毫安输出电流能力 外部编程复位延迟 故障保护反向电池保护60伏负载放电-50伏反向瞬态 短路保护热关断

作者头像 李华
网站建设 2026/6/6 16:30:11

如何用YOLOv9搭建实时检测系统?答案在这里

如何用YOLOv9搭建实时检测系统&#xff1f;答案在这里 YOLO系列模型自问世以来&#xff0c;就以“快、准、稳”成为工业界目标检测的首选。当YOLOv8还在广泛部署时&#xff0c;YOLOv9已悄然登场——它不是简单迭代&#xff0c;而是引入了可编程梯度信息&#xff08;PGI&#xf…

作者头像 李华