Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对象的引用计数通常存储在哪里?_C++_Smart Pointers - Fatal编程技术网

C++ 对象的引用计数通常存储在哪里?

C++ 对象的引用计数通常存储在哪里?,c++,smart-pointers,C++,Smart Pointers,如果我们有一些智能指针类,可以接受任意对象并提供引用计数指针,那么我们如何实际存储对引用计数的整数呢?引用计数必须在指向同一对象的智能指针类的所有实例之间共享 我想到的一个解决方案是将引用计数存储在我们所指向的对象中,但对于一般解决方案来说,这不是很好,因为每个对象都必须提供引用计数本身或从提供引用计数的某个对象继承。std::shared\u ptr使用的一般解决方案是分配一个单独的控制块,该控制块保存引用计数和其他内容,例如:析构函数,弱ptr计数 如果使用std::make_shared,

如果我们有一些智能指针类,可以接受任意对象并提供引用计数指针,那么我们如何实际存储对引用计数的整数呢?引用计数必须在指向同一对象的智能指针类的所有实例之间共享


我想到的一个解决方案是将引用计数存储在我们所指向的对象中,但对于一般解决方案来说,这不是很好,因为每个对象都必须提供引用计数本身或从提供引用计数的某个对象继承。

std::shared\u ptr使用的一般解决方案是分配一个单独的控制块,该控制块保存引用计数和其他内容,例如:析构函数,弱ptr计数

如果使用std::make_shared,则控制块和对象可以位于同一分配中


您在第二段中描述的东西也存在,例如:它在Boost中被调用。

std::shared_ptr使用的一般解决方案是分配一个单独的控制块,它保存引用计数和其他东西,例如:析构函数、弱_ptr计数

如果使用std::make_shared,则控制块和对象可以位于同一分配中


您在第二段中描述的东西也存在,例如:它在Boost中被称为。

它通常存储在设计对象所需的任何位置。侵入式智能指针需要与之配合使用的T来为引用计数提供存储。这就是为什么它们具有侵扰性;他们闯入这个物体

指定的设计可以采用任意对象。因此,一个侵入性的设计是不可能的

由于智能指针的多个实例必须访问同一引用计数对象,因此该引用计数必须独立于任何一个实例。由于它也必须独立于T,因此它必须是一个对象,其生存期与T和任何引用它的智能指针实例都无关

因此,智能指针在声明T的所有权时,还必须创建引用计数对象来管理它。通常,这是通过堆分配这样一个对象来完成的。智能指针的副本还获取指向引用计数的指针


这也是为什么让两个不同的std::shared_ptr构造函数声明同一个T*的所有权是非法的。您可以从已经拥有T*的共享ptr进行复制,但不能将T*本身直接传递给构造函数。由于T无法访问引用计数,shared_ptr的构造函数将不知道它是其他人拥有的,因此它将创建第二个引用计数块。

它通常存储在对象设计所需的任何位置。侵入式智能指针需要与之配合使用的T来为引用计数提供存储。这就是为什么它们具有侵扰性;他们闯入这个物体

指定的设计可以采用任意对象。因此,一个侵入性的设计是不可能的

由于智能指针的多个实例必须访问同一引用计数对象,因此该引用计数必须独立于任何一个实例。由于它也必须独立于T,因此它必须是一个对象,其生存期与T和任何引用它的智能指针实例都无关

因此,智能指针在声明T的所有权时,还必须创建引用计数对象来管理它。通常,这是通过堆分配这样一个对象来完成的。智能指针的副本还获取指向引用计数的指针


这也是为什么让两个不同的std::shared_ptr构造函数声明同一个T*的所有权是非法的。您可以从已经拥有T*的共享ptr进行复制,但不能将T*本身直接传递给构造函数。由于T无法访问引用计数,shared_ptr的构造函数将不知道它是其他人拥有的,因此它将创建第二个引用计数块。

根据您希望支持的操作,有许多存储引用计数的策略

这里的其他答案概括了一个选项,即在托管内存旁边分配一个辅助控制块,并使所有智能指针指向该辅助块。这使得快速确定准确的引用计数变得容易,但需要为每个智能指针分配额外的资源,这可能会使速度减慢一点,并且在内存不足时可能会失败。当控制块未与对象本身连续存储时,查找控制块的缓存友好性也存在问题

另一个选项是引用链接,其中没有显式引用计数。相反,您可以将一个循环的双链接列表穿入所有智能指针。添加新的智能poi时
对于对象,该智能指针将拼接到链接列表中,当删除智能指针时,该智能指针将从链接列表中拼接出来。这消除了对辅助分配的需要,除非(比如)您需要一个定制的删除器并改进了局部性,但这使得确定准确的引用计数非常昂贵。实际需要精确的引用计数有些不常见,因此这种折衷通常是合理的。

根据您希望支持的操作,有许多存储引用计数的策略

这里的其他答案概括了一个选项,即在托管内存旁边分配一个辅助控制块,并使所有智能指针指向该辅助块。这使得快速确定准确的引用计数变得容易,但需要为每个智能指针分配额外的资源,这可能会使速度减慢一点,并且在内存不足时可能会失败。当控制块未与对象本身连续存储时,查找控制块的缓存友好性也存在问题


另一个选项是引用链接,其中没有显式引用计数。相反,您可以将一个循环的双链接列表穿入所有智能指针。向对象添加新的智能指针时,该智能指针将拼接到链接列表中;删除智能指针时,该智能指针将从链接列表中拼接出来。这消除了对辅助分配的需要,除非(比如)您需要一个定制的删除器并改进了局部性,但这使得确定准确的引用计数非常昂贵。实际上需要精确的引用计数有些不常见,因此这种折衷通常是合理的。

共享的ptr不需要真正的T*。它可以有一个带有*的引用\u count\u block\u,其中既包含引用计数又包含TWhy not with the smart pointer类本身?一个共享的ptr不需要有一个T*。它可以有一个带有*的引用\u count\u block\u,其中既包含引用计数又包含TWhy not with the smart pointer类本身?拥有两个不同的std::shared_ptr是非法的,这是通过静态分析强制/强制执行的吗?@AvinKavish:这与取消引用空指针一样强制执行。拥有两个不同的std::shared_ptr是非法的,这是通过静态分析强制/可执行的吗?@AvinKavish:这就像取消引用空指针一样可执行。在这种情况下,如何准确地获得计数?由于所有内容都连接在一个循环列表中,您基本上只需遍历链接列表,直到返回到开始的位置,计算你一路上所走的步数。@AvinKavish:还应该注意的是,你几乎从来都不需要计算。您可能最想要求的是它是否是唯一拥有所有权的指针。在这种情况下,如何准确地获取计数?因为所有内容都连接在一个循环列表中,您基本上只需遍历链接列表,直到返回到开始的位置,计算你一路上所走的步数。@AvinKavish:还应该注意的是,你几乎从来都不需要计算。您可能最想要求的是它是否是唯一拥有所有权的指针。