首页 / 知识
关于stl:我可以在C中使用具有值语义的多态容器吗?
2023-04-14 00:50:00

Can I have polymorphic containers with value semantics in C++?通常,我更喜欢在C语言中使用值而不是指针语义(即,使用 不幸的是,当您要存储所有都源自同一基础的各种对象类型时,值集合不起作用。请参见下面的示例。
我的问题是:我可以吃蛋糕(值语义),也可以吃它(多态容器)吗?还是我必须使用指针? 由于不同类的对象将具有不同的大小,因此如果将它们存储为值,最终会遇到切片问题。 一种合理的解决方案是存储容器安全的智能指针。我通常使用boost :: shared_ptr,它可以安全地存储在容器中。请注意std :: auto_ptr不是。
shared_ptr使用引用计数,因此在删除所有引用之前,它不会删除基础实例。 我只想指出vector 将其与向量 在最坏的情况下,当您扫描向量 因此,请在适当的时候继续使用vector 是的,可以。 boost.ptr_container库提供标准容器的多态值语义版本。您只需要传递一个指向分配给堆的对象的指针,容器将获得所有权,并且所有其他操作将提供值语义,除了收回所有权之外,这通过使用智能指针为您提供了值语义的几乎所有好处。 。 您也可以考虑boost :: any。我已经将其用于异构容器。当读回值时,您需要执行any_cast。如果失败,它将抛出bad_any_cast。如果发生这种情况,您可以赶上下一个类型。 我相信,如果您尝试将一个派生类广播到其基类,它将抛出bad_any_cast。我试过了:
话虽如此,我也将先走shared_ptr路线!只是认为这可能会引起一些兴趣。 在寻找这个问题的答案时,我遇到了这个问题和一个类似的问题。在另一个问题的答案中,您将找到两个建议的解决方案: 包装器定义您的类所需的接口,并包含一个指向此类对象的指针。接口的实现是通过自由函数完成的。 这是此模式的示例实现:
然后将不同的形状实现为常规结构/类。您可以自由选择要使用成员函数还是自由函数(但是您必须更新以上实现以使用成员函数)。我更喜欢自由功能:
您现在可以将
此模式的缺点是,由于每个功能需要定义三次,因此它在界面中需要大量样板。
这将产生:
如果您担心 只需在已经说过的1800条信息中添加一件事即可。 您可能想看看Scott Mayers的"更有效的C","项目3:从不对数组进行多态处理",以便更好地理解此问题。 大多数容器类型都希望抽象出特定的存储策略,无论是链表,矢量,基于树还是您拥有的存储策略。因此,在拥有和食用上述蛋糕时会遇到麻烦(即蛋糕是谎言(注意:有人得开玩笑))。 那该怎么办?好了,有一些可爱的选项,但是大多数选项都会简化为以下几个主题之一或它们的组合:选择或发明合适的智能指针,以某种巧妙的方式使用模板或模板模板,使用包含对象的通用界面为实现每个容器的双重调度提供了一个钩子。 这两个既定目标之间存在基本的紧张关系,因此您应该确定所需的内容,然后尝试设计一些基本可以使您获得所需内容的东西。可以做一些不错的和意想不到的技巧,以使指针看起来像具有足够聪明的引用计数和足够聪明的工厂实现的值。基本思想是使用引用计数,按需复制和constness,以及(针对该因素)预处理器,模板和C的静态初始化规则的组合,以获取关于自动化指针转换的尽可能智能的信息。 过去,我花了一些时间来尝试设想如何使用虚拟代理/信封信/带有引用计数指针的可爱技巧来完成类似C语言中值语义编程的基础。 我认为可以做到,但是您必须在C中提供一个相当封闭,类似C#托管代码的世界(尽管您可以在需要时从中进入基础C)。因此,我很同情您的思路。
请勿执行此操作。首先,这会否定您要实现的多态性! 我正在使用自己的具有公开值类型语义的模板化集合类,但在内部它存储指针。它使用了一个自定义的迭代器类,该类在取消引用时会得到值引用,而不是指针。复制集合将进行深层项目复制,而不是重复的指针复制,这就是大多数开销所在的地方(这是一个很小的问题,考虑到我所得到的)。 这个想法可以满足您的需求。 |
最新内容
相关内容
linux默认命令删除?
linux默认命令删除?,系统,软件,名称,档案,命令,文件,目录,不了,电脑,文件夹,关于linux的删除命令1、命令格式:rm [选项] 文件… 命令功能:删除一linux下删除命令行?
linux下删除命令行?,系统,数据,命令,文件,名称,百度,环境,不了,档案,文件夹,linux删除文件命令1、linux 删除文件指令:输入rd盘符名:\文件夹名linux删除挂载命令?
linux删除挂载命令?,系统,设备,电脑,信息,管理,网络,名字,密码,文件,命令,linuxyum挂载到目录不能删除吗?1、执行下面的命令转移到yum源目录1clinux改语言命令行?
linux改语言命令行?,系统,环境,工具,密码,概念,地方,软件,通信,管理,国际,linux命令行下怎样改变语言将内容改为:LANG=zh_CN.UTF-8LANGUAGE=zh_linux删除空行命令?
linux删除空行命令?,名称,不了,命令,文件夹,文件,时间,工作,简介,情况,资料,linux如何清除csv文件空行1、linux如何清除csv文件空行?答案如下:首linux删除软件命令?
linux删除软件命令?,软件,系统,命令,不了,名称,数据,文件夹,文件,工具,百度,linux软件卸载命令1、linux卸载软件命令:apt-get,aptitude。Linux软linux命令行c语言?
linux命令行c语言?,代码,系统,工具,环境,工作,保险,发行,命令,文件,终端,linux终端下如何进行C语言编译1、在Linux下面,如果要编译一个C语言源c语言在linux命令?
c语言在linux命令?,系统,工作,管理,命令,保险,基础,环境,信息,文件,语言,linux系统的命令是什么linux常用命令有pwd命令、cd命令、ls命令、catlinux删除集群命令?
linux删除集群命令?,软件,管理,工具,平台,工作,系统,技术,数据,公司,产品,在linux里怎么删除grid集群软件1、linux怎么卸载软件呢,下面就让我们linux输入命令删除键?
linux输入命令删除键?,名称,系统,档案,命令,文件,目录,不了,数据,文件夹,终端,linux删除命令是什么Linux的文件和目录的删除命令有:rm、rmdir、linux删除群组的命令?
linux删除群组的命令?,系统,管理,工作,名称,命令,地址,邮箱,基础,密码,用户组,linux基础命令linux系统常用操作命令如下:ls:全拼list,功能是列出删除密码命令linux?
删除密码命令linux?,密码,系统,管理,电脑,软件,百度,信息,名称,名字,命令,linux登录密码忘了linux密码忘了怎么办第一步需要重新启动的linux系