C++为什么采用自由函数:
std::make_unique(...);
std::make_shared(...);
不要使用静态成员函数:
std::unique_ptr::make(...); // static
std::shared_ptr::make(...); // static
?
C++为什么采用自由函数:
std::make_unique(...);
std::make_shared(...);
不要使用静态成员函数:
std::unique_ptr::make(...); // static
std::shared_ptr::make(...); // static
?
friend
时,自由函数才能访问私有数据。选择将这些函数实现为自由函数(其中少数实现为友元函数)不是随意的历史遗物,而是有意为之,以提高封装性并为所有std::make_x
函数保持一致的命名方案。
在C++中有许多标准工厂函数:
std::make_pair
std::make_tuple
std::make_unique
std::make_shared //efficiency
std::make_exception_ptr //efficiency
std::make_move_iterator
std::make_reverse_iterator
std::make_error_code
std::make_error_condition
//And several more are proposed for C++17
x
的公共接口即可正确实现make_x
函数。在make_shared
和make_exception_ptr
的情况下,最有效的实现需要访问std::shared_ptr
或std::exception_ptr
的内部数据。其他所有功能都可以仅使用公共接口实现,零性能损失。make_shared
是唯一的类似工厂函数,那么它成为成员函数可能是有意义的,但由于大多数此类函数不需要成为friend
函数才能有效运行,为了保持一致性,make_shared
也实现为自由函数。make
,除了make_shared
和make_exception_ptr
之外的每种情况下,成员函数将不可避免地过度访问x
对象的私有数据。采用标准化设计后,只有少数需要访问私有数据的make_x
函数可以标记为friend
,其余默认正确尊重封装性。如果在某些情况下使用非成员make_x
,在其他情况下使用静态成员make
,则标准库将变得不一致且更难以学习。一致性.
我认为没有什么必要使用::make
语法而不是当前的语法。我假设make_unique
和make_shared
被优先选择,以保持与现有std::make_pair
和std::make_heap
函数的一致性,这些函数在C++11之前就已经存在了。
请注意,std::make_pair
具有一个很大的优点:它自动从函数调用中推断出结果对的类型:
auto p0 = std::make_pair(1, 1.f); // pair<int, float>
如果我们有std::pair::make
,那么我们将不得不编写:
auto p1 = std::pair<int, float>::make(1, 1.f);
这将违背make_pair
的本意。
因此,我认为选择make_unique
和make_shared
是因为开发人员已经习惯了make_pair
和类似的函数。
make_pair
被选择而不是使用pair::make
是因为前者有上述的好处。
make_pair
,而是关于 make_unique
。无论如何,在 unique_ptr<T>::make
和 make_unique<T>
中都必须指定返回类型。 - David Haimmake_pair
而不是可能存在的pair::make
。后来可能选择了make_unique
而不是unique_ptr::make
,因为已经存在make_pair
。 - Vittorio Romeostd::make_pair
已经存在,库的用户会期望创建函数是以 std::make_...
开头的独立函数。 - Galik这对于 make_***
并不新鲜,还有其他例子存在:
std::this_thread::XXXX
取代 std::thread::XXXX_current
即使将与当前执行线程相关的函数作为静态函数放置在 thread
类中是有意义的,但它们是全局性质的,位于 this_thread
命名空间内。
同样,我们可以像 std::container::sort
这样拥有一个帮助容器的辅助类 std::container
,但我们有的是 std::sort
。
make
函数。 - vladonstd::pair<int, float>{42, 3.14f}
:) - Quentin