- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些使用shared_ptr
的代码作为在我的应用程序中引用特定类型对象(称为T
)的标准方法。为了提高效率,我尝试谨慎使用make_shared
和std::move
和const T&
。但是,我的代码花了很多时间传递shared_ptr
s(我包裹在shared_ptr
中的对象是整个caboodle的中心对象)。更重要的是,shared_ptr
通常指向一个对象,该对象用作“无值”的标记;该对象是特定T
子类的全局实例,并且由于其refcount永远不会为零,因此它可以永久存在。
使用“无值”对象很不错,因为它以良好的方式响应发送到这些对象的各种方法,并表现出我希望“无值”的行为。但是,性能指标表明,我的代码中花费了大量时间来增加和减少该全局单例对象的refcount,使新的shared_ptr
引用该对象,然后销毁它们。举个例子:对于一个简单的测试用例,如果我将nullptr
粘贴在shared_ptr
中以指示“无值”,而不是使它们指向全局单例T
“无值”对象,则执行时间从9.33秒减少到7.35秒。这是非常重要的区别。如果运行在更大的问题上,该代码将很快用于在计算集群上进行多日运行。所以我真的需要加快速度。但是我也很想拥有我的“无值(value)”对象,这样我就不必在我的所有代码中都检查nullptr
,对此情况进行了特殊的处理。
所以。有没有办法吃我的蛋糕呢?特别是,我在想我可以通过某种方式将shared_ptr
子类化为一个可以与“无值”对象一起使用的“shared_immortal_ptr”类。子类的行为就像普通的shared_ptr
一样,但是它根本不会增加或减少其引用计数,并且会跳过所有相关的簿记。这样的事情可能吗?
我也在考虑制作一个内联函数,该函数可以在get()
上执行shared_ptr
,并且如果get()
返回nullptr
,则可以替换指向单例不朽对象的指针;我想,如果我在代码中的任何地方都使用了它,而从未在*
上直接使用->
或shared_ptr
,那我会被隔离。
还是针对这种情况,我还没有遇到另一个好的解决方案?
最佳答案
Galik询问了有关您的遏制策略的中心问题。我假设您已经考虑到这一点,并且有理由依赖shared_ptr作为一种公共(public)遏制策略,没有其他选择。
我不得不提出似乎有争议的建议。您所定义的是,您需要一种类型的shared_ptr,它永远不会有nullptr,但是std::shared_ptr
不会这样做,并且我检查了STL的各种版本,以确认提供的客户删除器不是解决方案的入口点。
因此,可以考虑制作自己的智能指针,也可以采用根据需要进行更改的指针。基本思想是建立一种shared_ptr,可以指示该shadow_pointer将其影子指针指向它不拥有的全局对象。
您有std::shared_ptr
的源代码。该代码不便于阅读。可能很难使用。这是一种途径,但是您当然可以复制源代码,更改 namespace 并实现所需的行为。
但是,在90年代中期将模板首次引入时代的编译器时,我们所有人要做的第一件事就是开始构建容器和智能指针。智能指针非常容易编写。它们很难设计(或曾经设计过),但是随后您有一个要建模的设计(您已经使用过)。
您可以实现shared_ptr的基本接口(interface)来创建替换对象。如果您很好地使用了typedef,则应该只在少数几个地方进行更改,但是至少搜索和替换将相当不错。
这是我建议的两种方法,两种方法都具有相同的功能。从库中采用shared_ptr,或者从头开始制作一个。您会惊讶地如此迅速地进行替换。
如果您采用std::shared_ptr
,则主要主题是了解shared_ptr如何确定应减少的值。在大多数实现中,shared_ptr必须引用一个节点,在我的版本中,它称为控制块(_Ref)。当引用计数达到零时,节点拥有要删除的对象,但是如果_Ref为null,则shared_ptr自然跳过该对象。但是,->和*之类的运算符或get函数不会费心检查_Ref,它们只是返回阴影或_Ptr(在我的版本中)。
现在,当调用重置时,_Ptr将设置为nullptr(或在我的源代码中为0)。分配给另一个对象或指针时将调用Reset,因此,即使使用对nullptr的分配,此操作也有效。关键是,对于您需要的这种新型的shared_ptr,您可以简单地更改行为,以便每当发生这种情况(重置为nullptr)时,都将_Ptr(shared_ptr中的阴影指针)设置为“无全局值”对象地址。
*,get或->的所有用法都将返回该无值对象的_Ptr,并且在另一个赋值中使用时将正确运行,或者再次调用reset,因为这些函数不依赖于影子指针来作用于节点,并且由于在这种特殊情况下该节点(或控制块)将为nullptr,因此shared_ptr的其余部分将表现为好像正确指向了nullptr一样-即,不删除全局对象。
显然,将std::pointer
更改为此类特定于应用程序的行为听起来很疯狂,但是坦率地说,这是性能工作使我们难以做的事情。否则会发生奇怪的事情,例如为了获得更高的C原始速度而偶尔放弃C++或汇编程序。
修改std::shared_ptr
源(作为副本用于此特殊目的)不是我要选择的(事实上,我已经遇到了您的情况的其他版本,因此数十年来我已经多次做出了选择)。
为此,我建议您构建一个基于策略的智能指针。我觉得很奇怪,我今天早些时候(或昨天,凌晨1:40)在另一篇文章中提出了这个建议。
我指的是Alexandrescu于2001年写的书(我认为这是Modern C++,有些单词我不记得了)。他介绍了loki,其中包括基于策略的智能指针设计,该设计仍在他的网站上发布并免费提供。
我认为,这个想法应该已经合并到shared_ptr中。
基于策略的设计被实现为模板类的范例,该模板类是从一个或多个参数中派生的,如下所示:
template< typename T, typename B >
class TopClass : public B {};
std::shared_ptr
和
std::weak_ptr
是单独的类,它们作为一个家族与其他家族(节点或控制块)进行交互,以提供智能指针服务。但是,在我多次使用的设计中,这两个是由同一顶级模板类构建的。在该设计中,shared_ptr和weak_ptr之间的区别在于模板的第二个参数中提供的附件策略。如果使用弱连接策略作为第二个参数实例化该类型,则它是一个弱指针。如果给出了强有力的附件策略,那将是明智的选择。
std::shared_ptr
不提供)。接口(interface)和许多代码是共享的,但是可以通过选择不同的策略来简单地构建几种不同类型的智能指针。要更改行为,可以在不更改现有代码的情况下插入新策略。目前,我同时使用了std::shared_ptr(几年前在boost时使用的)和我几年前开发的MetaPtr库,后者在我需要高性能或灵活选项(如您的库)时使用。
关于c++ - 有没有一种方法可以针对永久对象优化shared_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32774424/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!