Update item19.md

Co-authored-by: Yang Yi <qingfeng.yy@alibaba-inc.com>
This commit is contained in:
猫耳堀川雷鼓 2021-02-20 21:07:24 +08:00 committed by GitHub
parent c614417bae
commit b38c471c7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -99,7 +99,7 @@ void Widget::process()
processedWidgets.emplace_back(this); //然后将它加到已处理过的Widget
} //的列表中,这是错的!
```
评论已经说了这是错的——或者至少大部分是错的。(错误的部分是传递`this`,而不是使用了`emplace_back`。如果你不熟悉`emplace_back`,参见[Item42](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/8.Tweaks/item42.md))。上面的代码可以通过编译,但是向`std::shared_ptr`的容器传递一个原始指针(`this``std::shared_ptr`会由此为指向的`Widget``*this`)创建一个控制块。那看起来没什么问题,直到你意识到如果成员函数外面早已存在指向那个`Widget`对象的指针它是未定义行为的Game, Set, and Match译注一部关于网球的电影但是译者没看过。句子本意“压倒性胜利比赛结束”
注释已经说了这是错的——或者至少大部分是错的。(错误的部分是传递`this`,而不是使用了`emplace_back`。如果你不熟悉`emplace_back`,参见[Item42](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/8.Tweaks/item42.md))。上面的代码可以通过编译,但是向`std::shared_ptr`的容器传递一个原始指针(`this``std::shared_ptr`会由此为指向的`Widget``*this`)创建一个控制块。那看起来没什么问题,直到你意识到如果成员函数外面早已存在指向那个`Widget`对象的指针它是未定义行为的Game, Set, and Match译注一部关于网球的电影但是译者没看过。句子本意“压倒性胜利比赛结束”
`std::shared_ptr`API已有处理这种情况的设施。它的名字可能是C++标准库中最奇怪的一个:`std::enable_shared_from_this`。如果你想创建一个用`std::shared_ptr`管理的类,这个类能够用`this`指针安全地创建一个`std::shared_ptr``std::enable_shared_from_this`就可作为基类的模板类。在我们的例子中,`Widget`将会继承自`std::enable_shared_from_this`