C++ 为什么std::共享“ptr被认为是”;沉重的;及;“昂贵”;,但是std::array“;与普通(c型)阵列性能相同;?

C++ 为什么std::共享“ptr被认为是”;沉重的;及;“昂贵”;,但是std::array“;与普通(c型)阵列性能相同;?,c++,c++11,C++,C++11,我不太明白为什么std::shared_ptr被认为是“重的”和“昂贵的”,但std::array“与普通(c风格)数组具有相同的性能”?在共享ptr中,我们有指针和两个计数器:用于共享引用和弱引用。在std::array中,我们有指向数据的指针及其大小(基本上与shared_ptr中指针的计数相同)。似乎是相同的开销,尽管它写的是“具有C风格数组的性能和可访问性” 在std::array中,我们有指向数据的指针及其大小(基本上与shared_ptr中指针的计数相同) 这是不正确的标准::数组基

我不太明白为什么std::shared_ptr被认为是“重的”和“昂贵的”,但std::array“与普通(c风格)数组具有相同的性能”?在共享ptr中,我们有指针和两个计数器:用于共享引用和弱引用。在std::array中,我们有指向数据的指针及其大小(基本上与shared_ptr中指针的计数相同)。似乎是相同的开销,尽管它写的是“具有C风格数组的性能和可访问性”

在std::array中,我们有指向数据的指针及其大小(基本上与shared_ptr中指针的计数相同)

这是不正确的<代码>标准::数组基本上是

template <typename T, std::size_t N>
struct array
{
    T data[N];
};
模板
结构体数组
{
T数据[N];
};
没有分配、指针或额外的大小变量。它只是包装了一个原始数组,并提供了使其成为容器的函数

另一个上的
std::shared_ptr
持有指针,需要动态分配指向的对象。它还需要引用计数,这需要以线程安全的方式完成,这会引入大量开销

这就是为什么
array
是“零成本抽象”,而
shared\u ptr
不是

在std::array中,我们有指向数据的指针及其大小

std::array
无需将其大小存储在任何位置,更不用说将其存储在每个对象中。对于给定类型,
std::array::size()
的值在编译时已知。(不要忘记,
std::array
std::array
是不同的类型。)

模板
constexpr std::size\u t std::array::size()
{
返回N;
}

这是一种可能的实现。它可能是一个
静态
成员函数。

为什么您认为
std::array
std::shared\u ptr
具有相同的开销?没有动态分配,没有指针,没有运行时大小,没有引用计数。std::array没有指针。它有一个数组
sizeof(std::array)==sizeof(T)*N
(可能稍大一点,但我在实践中从未遇到过)。我想,您不太理解
std::array
的概念。与C-array相比,
std::array
上没有额外的数据成员或运行时操作,这就是为什么它具有完全相同的“成本”。@Justin我认为当
std::array
的大小与
T[N]
shared\u ptr有一个指向数据的指针,和另一个指向控制块的指针,该控制块包含两个原子引用计数器。访问计数器需要内存间接,如果它们不在缓存中,则代价很高。值得注意的是, UnQuyGPPT/<代码>是C++内存管理的零成本抽象。
template < class T, std::size_t N >
constexpr std::size_t std::array<T,N>::size()
{
    return N;
}