diff --git a/4.SmartPointers/item19.md b/4.SmartPointers/item19.md index 32b5d1e..96cd15f 100644 --- a/4.SmartPointers/item19.md +++ b/4.SmartPointers/item19.md @@ -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`: