Home  >  Q&A  >  body text

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 days ago728

reply all(2)I'll reply

  • ringa_lee

    ringa_lee2017-04-17 13:08:45

    I just happened to see it and tried to answer it. I hope the questioner can provide some reference.
    make_shared applies for less memory than a new raw pointer directly, because a new ptr applies for memory once. When the ptr is passed to the shared ptr, the shared ptr applies for a space to save the ptr.
    This is not the main problem. The problem is that if an exception occurs when you use new to construct this ptr, a memory leak will occur (no one will help you return the requested heap memory). If you use make_shared, even if the construction fails, the destructor of shared ptr can wipe your butt.
    For details, see Item 21 in Effective Modern C++ by Scott Meyers

    reply
    0
  • 伊谢尔伦

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

    is for dynamic binding. make_shared<WordQuery> gets a WordQuery type shared pointer, and dynamic binding from Query_base to WordQuery cannot be achieved.
    The reason why q(std::make_shared<WordQuery>(s)) reports an error is that the initialization parameters are incorrect. Changing s to WordQuery(s) can compile and pass, but it is static binding and cannot achieve the design goal.
    By the way, even if you use make_shared<Query_base>(WordQuery(s)) to implement the pointer, it will not work and an error will be reported. Even if a derived class is convertible, the derived class object collapses into a base class object, discarding the derived class members. Programming goals are still not achieved.

    reply
    0
  • Cancelreply