有些情况下,与启动STL一些功能make_前缀一样std::make_pair,std::make_shared,std::make_unique等它为什么一个更好的做法是使用它们,而不是简单地使用构造?
auto pair2 = std::pair< int, double >( 1, 2.0 );
auto pair3 = std::make_pair( 1, 2.0 );
std::shared_ptr< int > pointer1 = std::shared_ptr< int >( new int( 10 ) );
std::shared_ptr< int > pointer2 = std::make_shared< int >( 10 );
Run Code Online (Sandbox Code Playgroud)
小智 17
除了启用参数推断的好处(如其他答案中已经提到的),还有一些其他好处.
std::make_pair<T1, T2>注意不要简单地返回std::pair<T1, T2>.如果使用传入值std::ref,则返回的对不会存储std::reference_wrapper,它将存储引用.
std::make_shared可以结合分配.shared_ptr需要一些地方来保存诸如refcount,弱指针列表等无法直接存储的内容shared_ptr.这些可以与正在创建的对象组合在一个略大的块中,而不是在两个单独的块中.
std::make_sharedstd::make_unique如果抛出异常,两者都要确保没有任何对象遗留下来.如果将函数调用为f(std::shared_ptr<int>(new int), std::shared_ptr<int>(new int)),则编译器可能首先分配两个int对象,然后构造两个shared_ptr<int>对象.如果第二次分配失败,并且shared_ptr<int>尚未设置任何对象以在销毁时释放内存,则会出现内存泄漏.std::make_shared而std::make_unique结合的分配int和建设std::shared_ptr<int>中的一个函数调用,以及其他配置int和其他建筑std::shared_ptr<int>在另一个函数调用.函数调用不能重叠,因此如果第二次分配失败,则已经存在一个将被销毁的共享指针,同时撤消第一次分配.
虽然这可能是主观的,但这项技术的一个主要好处是:
编写针对接口的代码,而不是实现
本质上,函数模板实例化基于您传递的参数执行类型推导,而类模板实例化则不会.因此,您不必像直接实例化类那样传递模板参数.
应该注意的是,这不是关于"保存一些字符",而是关于使代码更通用,并避免与函数调用中的具体类型绑定.
但是,情况并非总是如此,正如您的std::make_shared示例所示,仍然存在必须将类型作为模板参数传递的情况.但是,正如Herb Sutter指出的那样,在使用时还有其他几个优点std::make_shared:
你应该首先写清楚和正确,并std::make_shared实现这两者(主观,但我同意)
使用std::make_shared更高效,因为它shared_ptr一次性分配您的对象以及对象,从而允许更低的分配开销和更好的缓存对齐.
| 归档时间: |
|
| 查看次数: |
1902 次 |
| 最近记录: |