- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在过去的几年里,我主要是一名 C 开发人员,偶尔会编写一些 Python 代码。由于存在大量相互矛盾的来源,我正在努力找出在现代 C++ 中管理系统资源的正确方法。
我是 libgpiod 的作者- 一个通过字符设备控制 GPIO 的库(这是从用户空间管理 GPIO 的新方法,与现在已弃用的 sysfs 接口(interface)相反)。核心库代码是用 C 编写的,但我计划从 C++11 开始为其他语言提供绑定(bind)。
我不想详细介绍 GPIO 是什么,但一般来说,GPIO 线是一个可配置的引脚,我们可以控制它与 GPIO 芯片相关联,通常会暴露多条线。 C 库使用两个核心结构对这种两级层次结构进行建模:struct gpiod_chip
和struct gpiod_line
。两者都仅作为使用提供的 API 函数操作的不透明指针对用户可见。在内部,芯片与一个打开的文件描述符(位于 /dev/ 中的设备文件)和几个包含对象状态的变量相关联。
一个指向已分配芯片对象的指针从 gpiod_chip_open()
变体之一返回给用户。用户负责使用 gpiod_chip_close()
释放分配的资源。与大多数低级 C 代码一样,用户的任务是管理资源句柄。该库是明确的线程感知的(因为没有全局状态)但不是线程安全的。
芯片管理与其关联的所有线对象的资源,因此我下面的问题仅与芯片相关。
根据我目前所读的内容,在现代 C++ 中,通常不应手动使用 new 和 delete 运算符。因此,我对芯片类的最初想法是:
namespace gpiod {
class chip {
// [snip!]
private:
std::shared_ptr<::gpiod_chip> _m_chip;
};
}
这将使芯片类持有对 gpiod_chip 对象的引用。复制和移动构造函数和赋值运算符将简单地使用 shared_ptr 的引用计数来允许自由移动和复制芯片对象。当引用计数降为 0 时,自定义删除器将调用 C 对象上的 gpiod_chip_close()
。
但后来我注意到有些人建议在这种情况下使用工厂并让用户将对象包装在他们自己选择的智能指针中。
就现代 C++ 而言,对于我的用例的正确方法有什么建议吗?
最佳答案
没有必要使用 std::shared_ptr
除非您需要资源具有共享所有权,而在您的示例中似乎并非如此。大多数时候,只需要使用 std::unique_ptr
即可,它会在其构造函数中获取指针的所有权,然后在其析构函数中使用 delete
销毁该指针。你说你的库主要是用 C 实现的,所以 gpiod_chip_open()
返回的指针可能是用 malloc
分配的,所以用 delete
销毁它是未定义的行为。要解决此问题,您可以为 std::unique_ptr
指定一个自定义删除仿函数,它将调用 gpiod_chip_close()
其析构函数而不是 delete
。
你可以这样做:
#include <memory>
struct gpiod_chip_deleter {
void operator()(::gpiod_chip* chip) noexcept {
::gpiod_chip_close(chip);
}
};
using gpiod_chip_ptr = std::unique_ptr<::gpiod_chip, gpiod_chip_deleter>;
// ...
gpiod_chip_ptr chip(::gpiod_chip_open());
// ...
关于C++11 及更高版本 : shared_ptr for managing system resources provided by a low-level C library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47001618/
我有一个 DIV #page,如果我在顶部添加边距,突然出现一个滚动条,即使该元素不大于主体。我怎样才能去掉滚动条? (参见 Fiddle) 我的 HTML I am a div siz
function getClosestValue(standardArray, targetVal) { standardArray = standardArray.sort(function(a,
我有 318x424 的书籍封面图片,我想做的是指定一张图片,并在其下方添加一个文本链接。初始 src 是 about:blank,这样如果响应式设计不显示框架,它就不会占用用户带宽。 框架的 HTM
我被这个问题困了两天了,还是没搞定。 基本上,我有一个二维数组,其中包含某些数字(在给定范围内)之间的关系: 0 = 顺序无关紧要 1 = 第一个数字(左栏中的数字)应该是第一个 2 = 第二个数字(
只有当我在更高的 API 上进行调试时,我才会强制关闭脚本:16,但是当涉及到 API 时它工作正常:10。这可能是我的项目设置问题吗? 这是对服务器的简单请求,以获取 fragment 中的类别列表
给定下表books id | listorder ----+----------- 3 | 1 2 | 2 1 | 3 4 |
我想要那个密码切换功能,好像TextInputLayout有这个功能,而不是 TextInputEditText .但是正如您在下面的代码中看到的,即使我将高度设置为 wrap_content和 ap
似乎从 读取给出空列表,它主要发生在延迟较高的网络上的主机上。是否有更强大的与远程主机交互的方式? use Net::SSH2; # my $ssh = Net::SSH2->new(); # ..
为了在 Play 商店中发布我的应用程序,我必须将 TargetSdkVersion 从 23 更改为 26。在我更改它之前,该应用程序运行良好!现在应用程序在启动时崩溃。我想通了,问题出在这两行:
我尝试了很多解决方案,但找不到一个。我有 3 个不同的列,其中包含不同类型的文本,我需要它们具有相同的高度。但它们是这样不同的:colums有人可以帮忙吗? 代码: .col-sm-2{
我尝试将一个 div 相对于其具有负顶值的父级定位。这工作正常,现在的问题是这个 div,即使它有一个负的 top 值也会使父 div 更大。 我该怎么做才能让父 div 不那么大? Here's a
这是一个一般性问题,可能适用于任何给定的语言,如 C、C++、Java 等。 我认为无论以何种方式实现它,都不会比使用 2 个循环更高效,后者的效率为 n^2。 for(i=0;i O(1) ),要么
我需要查找所有有订单的家庭。我根本不关心订单的数据,只关心它的存在。 (使用 SQL Server) 这样说是不是更有效率: SELECT HouseholdID, LastName, FirstNa
我有一个 UINavigationController,在屏幕顶部有一个 UINavigationBar,在底部有一个 UIToolbar。我想让工具栏高一点。这是我的代码: CGRect toolb
我正在使用自定义字体。该字体在我的 Windows PC 上完美运行,但在我的 Mac (Yosemite OSX) 上运行不佳。正如您在图片中看到的,Mac 上的字体比 Windows 上的字体稍大
我正在尝试使用 FaSTLane 将我的应用程序作为 alpha 版本部署到 Play 商店,但出现此错误: Google Api 错误:multiApkShadowedActiveApk:任何设备都
我在这里找不到神奇的调味料。看起来 API 不支持它,所以我想我正在寻找一些 CSS 来使 slider 更大。 我得到的是左边的,但我想把它设计成右边的样子?任何 CSS 技巧或以前有人这样做过。
如果我运行这段代码: float a=1.123456789; printf("The float value is %f\n",a); double b=1.123456789876543 prin
我正在尝试使用 strip binary 来剥离我的目标文件。我在 gcc-7 上构建了最新的 binutils,但我的代码库使用 gcc-4.9.2。Binutils 是为 64 位架构构建的,我的
有没有办法让 iPhone 应用的“内容”区域感知到更大的导航栏? 类似这些问题: iOS: Adding a fixed image just below the navigation bar iO
我是一名优秀的程序员,十分优秀!