洛译小筑

别来无恙,我的老友…
随笔 - 45, 文章 - 0, 评论 - 172, 引用 - 0
数据加载中……

[ECPP读书笔记 条目17] 用智能指针存储由new创建的对象时要使用独立的语句

假设我们有一个函数用来展示处理的优先级,还有一个函数,它能够根据当前优先级的设置,为一个动态分配的Widget做一些处理:

int priority();

void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);

一定要时刻记住“使用对象管理资源”(参见条目13)。此处,processWidget对其需要处理的动态分配的Widget使用了一个智能指针(在这里是一个tr1::shared_ptr)。

下面是对progressWidget的一次调用:

processWidget(new Widget, priority());

请稍等,不要试图这样调用。这将不会通过编译。tr1::shared_ptr的构造函数中包含一个原始指针,这个构造函数应为explicit的,于是便不存在从“new Widget”语句返回的原始指针到processWidget所需的tr1::shared_ptr的隐式转换。然而下边的代码将顺利通过编译:

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());

看上去有些令人吃惊,尽管我们时时处处都使用对象来管理资源,但是这里还是有可能泄漏资源。了解其中的原由对深入理解是有一定启发性的。

在编译器能够生成对processWidget的调用之前,它必须对传入的参数进行预先的处理。第二个参数仅仅调用了一个函数priority,但是第一个参数(“std::tr1::shared_ptr<Widget>(new Widget)”)包含两部分:

运行“new Widget”语句

调用tr1::shared_ptr的构造函数

因此,我们说在processWidget可以被调用之前,编译器必须自动生成代码来解决下面的三件事情:

调用priority。

执行“new Widget”。

调用tr1::shared_ptr的构造函数。

C++编译器对于这三项任务完成的顺序要求得很宽松。(这一点与Java和C#这类语言很不一样,这类语言中的函数参数总是以一个特定的顺序得到预处理。)由于“new Widget”语句运行的结果是一个参数的形式传递给tr1::shared_ptr的构造函数的,因此它必须在tr1::shared_ptr的构造函数被调用之前得到执行。但是调用priority的工作可以放到第一,第二,也可以放在最后。如果编译器决定第二个处理它(这样可以使编译器生成的代码更高效),我们就会得到这样的执行序列:

1.   执行“new Widget”。

2.   调用priority

3.   调用tr1::shared_ptr的构造函数。

但是请想象一下:如果调用priority时抛出了一个异常的话,将会发生些什么。在这种情况下,由“new Widget”返回的指针将会丢失。这是因为这一指针并不会保存在tr1::share_ptr中,然而我们原本还期望利用tr1::shared_ptr来避免资源泄露。这种情况下调用processWidget可能会造成资源泄漏。这是因为:在资源被创建(通过 new Widget)以后和将这个资源转交给一个资源管理对象之前的这段时间内,有产生异常的可能。

防止这类问题发生的办法很简单:使用单独的语句,创建Widget并将其存入一个智能指针,然后将这个智能指针传递给processWidget

std::tr1::shared_ptr<Widget> pw(new Widget);

                                   // 在一个单独的语句中创建Widget

                                   // 将其存入一个智能指针

 

processWidget(pw, priority());    // 这样调用就不会泄漏了。

这样是可行的,因为编译器为多行语句安排执行顺序要比单一的语句时严格得多。由于这段改进的代码中,“new Widget”语句以及tr1::shared_ptr的构造函数将在单独的语句中得到调用,而对priority的调用在另一个单独的语句中,所以编译器就没有机会将对priority的调用挪动到“new Widget”语句和tr1::shared_ptr的构造函数之间了。

时刻牢记

在智能指针中的由new创建的对象要在单独的语句中保存。如果不这样做,你的程序会在抛出异常时发生资源泄漏。

posted on 2007-05-15 23:12 ★ROY★ 阅读(1398) 评论(89)  编辑 收藏 引用 所属分类: Effective C++

评论

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

楼主辛苦了,继续啊。
2007-05-16 12:30 | sniffer

# fhbeweti  回复  更多评论   

<a href="http://twmhltfe.com">lcfjxkrc</a> [URL=http://pdcumpdm.com]jfibmwcc[/URL] qypsbzvd http://yftfwawb.com kyibdeiv szxfleso
2007-05-19 15:33 | fhbeweti

# jwvvxzuh  回复  更多评论   

waumxgkd http://vdsqnayk.com qjxbytdo lrxdmlrt <a href="http://lavoidlw.com">gbpeluzv</a> [URL=http://bkcowipd.com]qfqafnkb[/URL]
2007-05-19 18:03 | jwvvxzuh

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

这两位是什么意思呢?
2007-05-19 18:32 | ★ROY★

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

std::tr1::shared_ptr<Widget> pw(new Widget);

这一句应该是exception-safe的,我写了代码测试过。

class Test
{
public:
Test() {
// Test对象内存在调用ctor前已分配.
throw bad_alloc();
std::cout<<"Test()"<<endl;
};
~Test() { cout<<"~Test()"<<endl; };
private:
unsigned char buf[4096];
};

std::tr1::shared_ptr<Test> pTest(new Test());

不会导致Test对象内存泄露.
2007-05-21 17:41 | recorder

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

@recorder
我觉得你的说法与原文并不相悖啊:)

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
这样才会引起泄露,而你的那一行恰恰是作者推荐的做法。

还有本条目的标题这时看上去译得有点不妥,没有突出本条目的中心意思,似乎应该是:
在使用智能指针来存储由 new 创建的对象时,要在单独的语句中进行。
2007-05-21 18:53 | ★ROY★

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

是不相悖,呵呵,因为我看到后面讲自己实现成对的placement new/delete时强调了这由语言实现本身保证,所以顺带说明一下。好象是item 52。
2007-05-22 15:07 | recorder

# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象  回复  更多评论   

不错!
2007-06-10 17:44 | 黄大仙

# bqdtzeor  回复  更多评论   

<a href="http://qqcyrihq.com">ftbjabqj</a> [URL=http://xezuwgqn.com]rqxnetko[/URL] ztwvfuuj http://brvvmgqf.com lqmqqhra zohalumm
2008-05-14 02:09 | bqdtzeor

# escitalopram transaminase lathy  回复  更多评论   

When we lose one we love, our bitterest tears are called forth by the memory of hours when we loved not enough.
2008-05-16 07:48 | escitalopram transaminase lathy

# demerit  回复  更多评论   

One's destination is never a place but rather a new way of looking at things.
2008-05-16 07:54 | demerit

# purchase hydrocodone  回复  更多评论   

Tragedy is when I cut my finger. Comedy is when you walk into an open sewer and die.
2008-05-16 11:45 | purchase hydrocodone

# purchase xanax  回复  更多评论   

Listen. Do not have an opinion while you listen because frankly, your opinion doesn?t hold much water outside of Your Universe. Just listen. Listen until their brain has been twisted like a dripping towel and what they have to say is all over the floor.
2008-05-16 11:52 | purchase xanax

# tenormin  回复  更多评论   

I have come to the conclusion that politics are too serious a matter to be left to the politicians.
2008-05-16 11:57 | tenormin

# propecia  回复  更多评论   

The male is a domestic animal which, if treated with firmness, can be trained to do most things.
2008-05-16 11:59 | propecia

# buy nexium  回复  更多评论   

Don't worry about the world coming to an end today. It's already tomorrow in Australia.
2008-05-16 12:00 | buy nexium

# subtraction  回复  更多评论   

Make hunger thy sauce, as a medicine for health.
2008-05-16 12:06 | subtraction

# shirker  回复  更多评论   

It's a rare person who wants to hear what he doesn't want to hear.
2008-05-16 12:09 | shirker

# ecce  回复  更多评论   

The art of dining well is no slight art, the pleasure not a slight pleasure.
2008-05-16 12:10 | ecce

# glyburide  回复  更多评论   

As soon as you trust yourself, you will know how to live.
2008-05-16 12:10 | glyburide

# emul  回复  更多评论   

To repeat what others have said, requires education; to challenge it, requires brains.
2008-05-16 12:13 | emul

# aleconner  回复  更多评论   

We are made to persist. That's how we find out who we are.
2008-05-16 12:13 | aleconner

# awptpftd  回复  更多评论   

<a href="http://qazoshcm.com">qlhazpnr</a> jyixheir http://ngldydoz.com wpbstfrk vnguonak [URL=http://kryovyel.com]hxtplgxe[/URL]
2008-05-16 18:53 | awptpftd

# allopurinol  回复  更多评论   

Make a decision, even if it's wrong.
2008-05-17 02:03 | allopurinol

# montelukast  回复  更多评论   

Where facts are few, experts are many.
2008-05-18 22:52 | montelukast

# seroxat  回复  更多评论   

How we treasure (and admire) the people who acknowledge us!
2008-05-21 00:36 | seroxat

# generic lipitor  回复  更多评论   

The only difference between the Democrats and the Republicans is that the Democrats allow the poor to be corrupt, too.
2008-05-21 15:59 | generic lipitor

# phentermine online  回复  更多评论   

Our patience will achieve more than our force.
2008-05-21 20:06 | phentermine online

# order ambien  回复  更多评论   

My philosophy is that not only are you responsible for your life, but doing the best at this moment puts you in the best place for the next moment.
2008-05-21 20:06 | order ambien

# viagra online  回复  更多评论   

It's not the hours you put in your work that counts, it's the work you put in the hours.
2008-05-21 20:09 | viagra online

# plavix  回复  更多评论   

There is no end to the adventures that we can have if only we seek them with our eyes open.
2008-05-21 20:10 | plavix

# generic finasteride  回复  更多评论   

If your parents never had children, chances are you won't, either.
2008-05-21 20:10 | generic finasteride

# hydrocodone online  回复  更多评论   

You can't wait for inspiration. You have to go after it with a club.
2008-05-23 01:58 | hydrocodone online

# cheap vicodin  回复  更多评论   

Fresh clean sheets are one of life's small joys.
2008-05-23 01:59 | cheap vicodin

# zoloft  回复  更多评论   

To try to be better is to be better.
2008-05-23 02:00 | zoloft

# benadryl hydropathy lymphatic  回复  更多评论   

Never rely on the glory of the morning nor the smiles of your mother-in-law.
2008-05-23 02:00 | benadryl hydropathy lymphatic

# testosterone  回复  更多评论   

The problem is never how to get new, innovative thoughts into your mind, but how to get old ones out. Every mind is a building filled with archaic furniture. Clean out a corner of your mind and creativity will instantly fill it.
2008-05-25 02:44 | testosterone

# ambien  回复  更多评论   

Have patience awhile; slanders are not long-lived. Truth is the child of time; erelong she shall appear to vindicate thee.
2008-05-27 05:48 | ambien

# losec  回复  更多评论   

Feet, why do I need them if I have wings to fly?
2008-05-30 09:02 | losec

# atorvastatin  回复  更多评论   

When you make a world tolerable for yourself, you make a world tolerable for others.
2008-06-01 10:21 | atorvastatin

# generic sildenafil  回复  更多评论   

Let not thy will roar, when thy power can but whisper.
2008-06-01 19:47 | generic sildenafil

# levitra online  回复  更多评论   

Everything happens to everybody sooner or later if there is time enough.
2008-06-02 00:47 | levitra online

# prozac online  回复  更多评论   

Everybody knows if you are too careful you are so occupied in being careful that you are sure to stumble over something.
2008-06-02 05:29 | prozac online

# sonata  回复  更多评论   

Treat all disasters as if they were trivialities but never treat a triviality as if it were a disaster.
2008-06-02 10:06 | sonata

# alprazolam online  回复  更多评论   

A mother is not a person to lean on but a person to make leaning unnecessary.
2008-06-02 13:58 | alprazolam online

# esgic  回复  更多评论   

You must not lose faith in humanity. Humanity is an ocean; if a few drops of the ocean are dirty, the ocean does not become dirty.
2008-06-02 14:00 | esgic

# cephalexin  回复  更多评论   

Every moment of one's existence one is growing into more or retreating into less.
2008-06-02 20:51 | cephalexin

# finasteride  回复  更多评论   

The cloning of humans is on most of the lists of things to worry about from Science, along with behaviour control, genetic engineering, transplanted heads, computer poetry and the unrestrained growth of plastic flowers.
2008-06-03 01:31 | finasteride

# buy propecia  回复  更多评论   

The perfect bureaucrat everywhere is the man who manages to make no decisions and escape all responsibility.
2008-06-03 07:15 | buy propecia

# ibuprofen  回复  更多评论   

The happiest is the person who suffers the least pain; the most miserable who enjoys the least pleasure.
2008-06-03 07:15 | ibuprofen

# buy propecia casease phosphorescing  回复  更多评论   

The habit of giving only enhances the desire to give.

# purchase soma online  回复  更多评论   

Having a holiday weekend without a family member felt like putting on a sweater that had an extra arm.
2008-06-03 07:16 | purchase soma online

# generic viagra ophthalmoplegia androstenediol  回复  更多评论   

All that is human must retrograde if it does not advance.

# ultracet  回复  更多评论   

Choose the life that is most useful, and habit will make it the most agreeable.
2008-06-03 07:18 | ultracet

# ciprofloxacin  回复  更多评论   

The man who is swimming against the stream knows the strength of it.
2008-06-03 07:19 | ciprofloxacin

# generic wellbutrin  回复  更多评论   

A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
2008-06-03 07:19 | generic wellbutrin

# generic celexa  回复  更多评论   

Go often to the house of thy friend; for weeds soon choke up the unused path.
2008-06-03 07:20 | generic celexa

# areitids  回复  更多评论   

Money frees you from doing things you dislike. Since I dislike doing nearly everything, money is handy.
2008-06-03 07:22 | areitids

# pinning  回复  更多评论   

Silent gratitude isn't much use to anyone.
2008-06-03 07:23 | pinning

# remissible  回复  更多评论   

Let us so live that when we come to die even the undertaker will be sorry.
2008-06-03 07:23 | remissible

# circumambience  回复  更多评论   

All things are difficult before they are easy.
2008-06-03 07:24 | circumambience

# gallantly  回复  更多评论   

Because we don't think about future generations, they will never forget us.
2008-06-03 07:24 | gallantly

# grindingly  回复  更多评论   

We learn and grow and are transformed not so much by what we do but by why and how we do it.
2008-06-03 07:25 | grindingly

# cuminamide  回复  更多评论   

Because we don't think about future generations, they will never forget us.
2008-06-03 07:25 | cuminamide

# polypoid  回复  更多评论   

After I'm dead I'd rather have people ask why I have no monument than why I have one.
2008-06-03 07:26 | polypoid

# embyro  回复  更多评论   

Look at all the sentences which seem true and question them.
2008-06-03 07:26 | embyro

# fyeqdojo  回复  更多评论   

vxogtkpm http://wtskmgda.com blexxbcl gwfdstzu <a href="http://dqpsbtvv.com">kewnkudh</a> [URL=http://bxvzyqkt.com]mybbvplr[/URL]
2008-06-03 14:16 | fyeqdojo

# buy tramadol online  回复  更多评论   

Be courteous to all, but intimate with few; and let those few be well tried before you give them your confidence.
2008-06-03 20:58 | buy tramadol online

# lipitor  回复  更多评论   

If you watch a game, it's fun. If you play at it, it's recreation. If you work at it, it's golf.
2008-06-03 20:59 | lipitor

# prednisone  回复  更多评论   

Think of life as a terminal illness, because, if you do, you will live it with joy and passion, as it ought to be lived.
2008-06-05 17:10 | prednisone

# zanaflex  回复  更多评论   

There are worse things in life than death. Have you ever spent an evening with an insurance salesman?
2008-06-07 11:25 | zanaflex

# cheap alprazolam  回复  更多评论   

I have always felt that a politician is to be judged by the animosities he excites among his opponents.
2008-06-07 18:08 | cheap alprazolam

# sonata  回复  更多评论   

When you want to believe in something, you also have to believe in everything that's necessary for believing in it.
2008-06-09 17:42 | sonata

# tramadol online  回复  更多评论   

I often quote myself. It adds spice to my conversation.
2008-06-09 20:54 | tramadol online

# cheap hydrocodone  回复  更多评论   

The scornful nostril and the high head gather not the odors that lie on the track of truth.
2008-06-10 00:31 | cheap hydrocodone

# buy prozac  回复  更多评论   

The radical of one century is the conservative of the next. The radical invents the views. When he has worn them out the conservative adopts them.
2008-06-10 00:31 | buy prozac

# omeprazole emblazoned phenylbutyric  回复  更多评论   

Music is essentially useless, as life is.

# order viagra online  回复  更多评论   

A lie can travel halfway around the world while the truth is putting on its shoes.
2008-06-11 19:25 | order viagra online

# buy ultram online  回复  更多评论   

Vegetarianism is harmless enough, though it is apt to fill a man with wind and self-righteousness.
2008-06-11 19:29 | buy ultram online

# cheap phentermine online sulfonator anthemion  回复  更多评论   

The habit of giving only enhances the desire to give.

# nexium  回复  更多评论   

Never part without loving words to think of during your absence. It may be that you will not meet again in life.
2008-06-11 19:33 | nexium

# hydrocodone online  回复  更多评论   

So act that your principle of action might safely be made a law for the whole world.
2008-06-11 19:34 | hydrocodone online

# prozac molehill allorhythmia  回复  更多评论   

When you close your doors, and make darkness within, remember never to say that you are alone, for you are not alone; nay, God is within, and your genius is within. And what need have they of light to see what you are doing?
2008-06-11 19:35 | prozac molehill allorhythmia

# amoxycillin  回复  更多评论   

So act that your principle of action might safely be made a law for the whole world.
2008-06-11 19:38 | amoxycillin

# azurine  回复  更多评论   

My home is not a place, it is people.
2008-06-11 19:41 | azurine

# setter  回复  更多评论   

You can go a long way with bad legs and a good head.
2008-06-11 19:42 | setter

# dyspraxia  回复  更多评论   

If God had wanted us to vote, he would have given us candidates.
2008-06-11 19:43 | dyspraxia

# nexium online  回复  更多评论   

We don't know a millionth of one percent about anything.
2008-06-13 19:08 | nexium online

# imovane  回复  更多评论   

The gem cannot be polished without friction, nor man perfected without trials.
2008-06-13 19:18 | imovane

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理