如下所示,这本书前面告诉我尽量用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;
};
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
伊谢尔伦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.