首頁  >  問答  >  主體

c++primer第15章最后部分的类为什么不用make_shared而是用new初始化shared_ptr?

如下所示,这本书前面告诉我尽量用make_shared初始化shared_ptr,这章中为何都是用new来初始化呢?难道是因为忘记更新第5版这章中的c++11的改动了吗?

class Query
{
    friend Query operator~(const Query&);
    friend Query operator|(const Query&, const Query&);
    friend Query operator&(const Query&, const Query&);
public:
    //! build a new WordQuery
    Query(const std::string& s) : q(new WordQuery(s))  //就是这里
    {
        std::cout << "Query::Query(const std::string& s) where s=" + s + "\n";
    }

    //! interface functions: call the corresponding Query_base operatopns
    QueryResult eval(const TextQuery& t) const
    {
        return q->eval(t);
    }
    std::string rep() const
    {
        std::cout << "Query::rep() \n";
        return q->rep();
    }

private:
    //! constructor only for friends
    Query(std::shared_ptr<Query_base> query) :
        q(query)
    {
        std::cout << "Query::Query(std::shared_ptr<Query_base> query)\n";
    }
    std::shared_ptr<Query_base> q;
};
PHP中文网PHP中文网2765 天前730

全部回覆(2)我來回復

  • ringa_lee

    ringa_lee2017-04-17 13:08:45

    剛好手邊看到了勉力答下,希望能題主提供些參考。
    make_shared比直接new一個raw pointer少申請一次內存,因為new一個ptr申請了一次內存,把這個ptr傳給shared ptr時,shared ptr申請了一份空間來保存這個ptr。
    這個並不是主要的問題,問題是如果當你用new來構造這個ptr時發生了異常,就會產生內存洩漏(沒人幫你歸還申請的堆內存)。如果你是用make_shared的話,就算建構失敗,shared ptr的析構函式也能幫你擦好屁股。
    詳情可見Scott Meyers的Effective Modern C++ 中Item21

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:08:45

    是為了動態綁定,make_shared得到的是WordQuery類型shared指針,無法實現從Query_base到WordQuery的動態綁定。
    q(std::make_shared(s))錯誤的原因是初始化參數不對,把s改成WordQuery(s)可以編譯通過,但是是靜態綁定,無法實現設計目標。
    順便一提,即便用make_shared(WordQuery(s))實作指標也不行,會報錯。即便派生類別可以轉換,派生類別物件也會塌陷為基底類別對象,而丟棄派生類別成員。依然無法實現程式設計目標。

    回覆
    0
  • 取消回覆