Posted on 2007-05-15 23:12
★ROY★ 阅读(754)
评论(89) 编辑 收藏 引用 所属分类:
Effective C++
第17条:
要在单独的语句中使用智能指针来存储由
new
创建的对象
假设这里有一个函数用来显示处理优先级,另一个函数根据当前优先级为一个动态分配的
Widget
做一些处理:
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
一定要时刻记住“使用对象管理资源”这一真理(参见第
13
条)。
processWidget
中可以使用智能指针来动态分配其需要处理的
Widget
。
下面是对
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)
”)包含两部分:
l
运行
“new Widget”
语句
l
调用
tr1::shared_ptr
的构造函数
因此,在
processWidget
可以被调用之前,编译器必须自动生成代码来解决下面的三件事情:
l
调用
priority
。
l
执行
“new Widget”
。
l
调用
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::shared_ptr
中,因此它很有可能会丢失,于是内存泄漏就发生了。在资源被创建以后和这个资源转交给一个资源管理对象之前的这段时间内,有可能发生异常,如果发生的话,那么调用
processWidget
就会造成资源泄漏。
防止这类问题发生的办法很简单:使用单独的语句,创建
Widget
并将其存入一个智能指针,然后将这个智能指针传递给
processWidget
:
std::tr1::shared_ptr<Widget> pw(new Widget);
//
在一个单独的语句中创建
Widget
//
并存入一个智能指针
processWidget(pw, priority()); //
这样调用就不会泄漏了。
这样是可行的,因为编译器为多行的语句安排执行顺序要比单一的语句时严格得多。由于这段改进的代码中,“
new Widget
”语句以及对
tr1::shared_ptr
的构造函数的调用在单独的语句中,对
priority
的调用在另一个单独的语句中,所以编译器就没有机会调换处理顺序了。
牢记在心
l
在单独的语句中使用智能指针来保存由
new
创建的对象。如果不这样做,你的程序会在抛出异常时发生资源泄漏。
Feedback
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-05-16 12:30 by
楼主辛苦了,继续啊。
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-05-19 18:32 by
这两位是什么意思呢?
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-05-21 17:41 by
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对象内存泄露.
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-05-21 18:53 by
@recorder
我觉得你的说法与原文并不相悖啊:)
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
这样才会引起泄露,而你的那一行恰恰是作者推荐的做法。
还有本条目的标题这时看上去译得有点不妥,没有突出本条目的中心意思,似乎应该是:
在使用智能指针来存储由 new 创建的对象时,要在单独的语句中进行。
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-05-22 15:07 by
是不相悖,呵呵,因为我看到后面讲自己实现成对的placement new/delete时强调了这由语言实现本身保证,所以顺带说明一下。好象是item 52。
# re: 【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象 回复 更多评论
2007-06-10 17:44 by
不错!
# escitalopram transaminase lathy 回复 更多评论
2008-05-16 07:48 by
When we lose one we love, our bitterest tears are called forth by the memory of hours when we loved not enough.
One's destination is never a place but rather a new way of looking at things.
# purchase hydrocodone 回复 更多评论
2008-05-16 11:45 by
Tragedy is when I cut my finger. Comedy is when you walk into an open sewer and die.
# purchase xanax 回复 更多评论
2008-05-16 11:52 by
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.
I have come to the conclusion that politics are too serious a matter to be left to the politicians.
The male is a domestic animal which, if treated with firmness, can be trained to do most things.
Don't worry about the world coming to an end today. It's already tomorrow in Australia.
Make hunger thy sauce, as a medicine for health.
It's a rare person who wants to hear what he doesn't want to hear.
The art of dining well is no slight art, the pleasure not a slight pleasure.
As soon as you trust yourself, you will know how to live.
To repeat what others have said, requires education; to challenge it, requires brains.
We are made to persist. That's how we find out who we are.
Make a decision, even if it's wrong.
Where facts are few, experts are many.
How we treasure (and admire) the people who acknowledge us!
# generic lipitor 回复 更多评论
2008-05-21 15:59 by
The only difference between the Democrats and the Republicans is that the Democrats allow the poor to be corrupt, too.
# phentermine online 回复 更多评论
2008-05-21 20:06 by
Our patience will achieve more than our force.
# order ambien 回复 更多评论
2008-05-21 20:06 by
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.
# viagra online 回复 更多评论
2008-05-21 20:09 by
It's not the hours you put in your work that counts, it's the work you put in the hours.
There is no end to the adventures that we can have if only we seek them with our eyes open.
# generic finasteride 回复 更多评论
2008-05-21 20:10 by
If your parents never had children, chances are you won't, either.
# hydrocodone online 回复 更多评论
2008-05-23 01:58 by
You can't wait for inspiration. You have to go after it with a club.
# cheap vicodin 回复 更多评论
2008-05-23 01:59 by
Fresh clean sheets are one of life's small joys.
To try to be better is to be better.
# benadryl hydropathy lymphatic 回复 更多评论
2008-05-23 02:00 by
Never rely on the glory of the morning nor the smiles of your mother-in-law.
# testosterone 回复 更多评论
2008-05-25 02:44 by
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.
Have patience awhile; slanders are not long-lived. Truth is the child of time; erelong she shall appear to vindicate thee.
Feet, why do I need them if I have wings to fly?
# atorvastatin 回复 更多评论
2008-06-01 10:21 by
When you make a world tolerable for yourself, you make a world tolerable for others.
# generic sildenafil 回复 更多评论
2008-06-01 19:47 by
Let not thy will roar, when thy power can but whisper.
# levitra online 回复 更多评论
2008-06-02 00:47 by
Everything happens to everybody sooner or later if there is time enough.
# prozac online 回复 更多评论
2008-06-02 05:29 by
Everybody knows if you are too careful you are so occupied in being careful that you are sure to stumble over something.
Treat all disasters as if they were trivialities but never treat a triviality as if it were a disaster.
# alprazolam online 回复 更多评论
2008-06-02 13:58 by
A mother is not a person to lean on but a person to make leaning unnecessary.
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.
Every moment of one's existence one is growing into more or retreating into less.
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.
# buy propecia 回复 更多评论
2008-06-03 07:15 by
The perfect bureaucrat everywhere is the man who manages to make no decisions and escape all responsibility.
The happiest is the person who suffers the least pain; the most miserable who enjoys the least pleasure.
# buy propecia casease phosphorescing 回复 更多评论
2008-06-03 07:15 by
The habit of giving only enhances the desire to give.
# purchase soma online 回复 更多评论
2008-06-03 07:16 by
Having a holiday weekend without a family member felt like putting on a sweater that had an extra arm.
# generic viagra ophthalmoplegia androstenediol 回复 更多评论
2008-06-03 07:17 by
All that is human must retrograde if it does not advance.
Choose the life that is most useful, and habit will make it the most agreeable.
# ciprofloxacin 回复 更多评论
2008-06-03 07:19 by
The man who is swimming against the stream knows the strength of it.
# generic wellbutrin 回复 更多评论
2008-06-03 07:19 by
A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
# generic celexa 回复 更多评论
2008-06-03 07:20 by
Go often to the house of thy friend; for weeds soon choke up the unused path.
Money frees you from doing things you dislike. Since I dislike doing nearly everything, money is handy.
Silent gratitude isn't much use to anyone.
Let us so live that when we come to die even the undertaker will be sorry.
# circumambience 回复 更多评论
2008-06-03 07:24 by
All things are difficult before they are easy.
Because we don't think about future generations, they will never forget us.
We learn and grow and are transformed not so much by what we do but by why and how we do it.
Because we don't think about future generations, they will never forget us.
After I'm dead I'd rather have people ask why I have no monument than why I have one.
Look at all the sentences which seem true and question them.
# buy tramadol online 回复 更多评论
2008-06-03 20:58 by
Be courteous to all, but intimate with few; and let those few be well tried before you give them your confidence.
If you watch a game, it's fun. If you play at it, it's recreation. If you work at it, it's golf.
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.
There are worse things in life than death. Have you ever spent an evening with an insurance salesman?
# cheap alprazolam 回复 更多评论
2008-06-07 18:08 by
I have always felt that a politician is to be judged by the animosities he excites among his opponents.
When you want to believe in something, you also have to believe in everything that's necessary for believing in it.
# tramadol online 回复 更多评论
2008-06-09 20:54 by
I often quote myself. It adds spice to my conversation.
# cheap hydrocodone 回复 更多评论
2008-06-10 00:31 by
The scornful nostril and the high head gather not the odors that lie on the track of truth.
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.
# omeprazole emblazoned phenylbutyric 回复 更多评论
2008-06-10 00:32 by
Music is essentially useless, as life is.
# order viagra online 回复 更多评论
2008-06-11 19:25 by
A lie can travel halfway around the world while the truth is putting on its shoes.
# buy ultram online 回复 更多评论
2008-06-11 19:29 by
Vegetarianism is harmless enough, though it is apt to fill a man with wind and self-righteousness.
# cheap phentermine online sulfonator anthemion 回复 更多评论
2008-06-11 19:31 by
The habit of giving only enhances the desire to give.
Never part without loving words to think of during your absence. It may be that you will not meet again in life.
# hydrocodone online 回复 更多评论
2008-06-11 19:34 by
So act that your principle of action might safely be made a law for the whole world.