- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
C++ 程序通常必须处理 C 库,这些库提供用于分配和释放资源的自由函数。为简化此示例,考虑两个 C 函数,如 get_resource()
和 free_resource()
。
考虑一个对象在其生命周期的某个时刻获取任何资源,并在对象被销毁或由于构建过程中的错误而未完全构建时自动释放它。
获得这种自动化的理想/简短/简单的习语是什么?下面是一个想法,但它使对象不能正确地默认移动。除了在析构函数中释放内存或检查构造函数中的错误以进行回滚之外,还有什么更好的方法吗?
struct Object {
void* my_get_resource() { // might be called from the constructor or any other point
return get_resource();
}
Object() : up(&resource, &del) {
resource = my_get_resource();
/* init all the stuff, but this init might fail at _many_ points */
}
//~Object() { if (resource) free_resource(resource); } // I don't like: collides with del and is not called if my_get_resource() is called from the constructor and the init process fails for some reasons
private:
void *resource = nullptr;
static void del(void ** ) noexcept {
if (*resource) { free_resource(resource); }
}
unique_ptr < void*, decltype(&del) > up; // RAII: almost good, sadly that makes Object not moveable properly without redefining the move constructor properly
};
最佳答案
显然您想要一个可移动的 RAII 包装器。
然后只需定义一个移动构造函数并声明一个 protected 或私有(private)的复制构造函数和复制赋值运算符。如果您不打算支持当前的 Visual C++,那么您可以将复制构造函数和复制赋值运算符声明为已删除。
这涉及在构造函数中检查错误并在析构函数中清理,这与您的要求不符......
Is there anything better which does not imply freeing memory from within the destructor or checking errors in the constructor to do rollbacks?
简而言之,这些要求通常与您发布的代码所指示的目标不兼容。
即使您使用 unique_ptr
来完成这项工作,它的工作方式也是通过在构造函数中检查错误并在析构函数中清理,这与您的(极不现实的)要求直接不符。
以下是如何开始“手动”做事:
bool hopefully( bool const c ) { return c; }
bool throwX( string const& s ) { throw std::runtime_error( s ); }
class Resource
{
private:
void* pResource;
Resource( Resource const& ); // Add "= delete" if all compilers support it.
Resource& operator=( Resource const& ); // Ditto.
public:
void* theValue() const { return pResource; } // Use problem-specific name.
~Resource()
{
if( pResource != 0 )
{
::freeResource( pResource );
}
}
Resource()
: pResource( ::getResource() )
{
hopefully( pResource != 0 )
|| throwX( "Resource::<init>: getResource failed" );
}
Resource( Resource&& other )
: pResource( other.pResource )
{
other.pResource = 0;
}
};
您可以添加移动赋值运算符。
并且您可以将其归纳为Handle
类模板。
免责声明:未经测试的现成代码,未经编译器处理。
关于c++ - 通过 C 接口(interface)分配和释放资源的正确用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13675090/
我有一个附加了 View Controller 的 AVAudioPlayer 实例。 @property (nonatomic, retain) AVAudioPlayer *previewAudi
我是java初学者。假设我声明了一个 Account 类型的变量 Account _account = new Account("Thomas"); 然后在其他地方我做了这样的事情: _account
我在我的应用程序中使用了 3 个 UIViewController,现在我想知道当我从另一个应用程序切换到另一个 UIViewController 时释放它们是否是一个好主意。显然,这将是隐藏的,当它
我分配了一个直接缓冲区: ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 我读过: Deallocating Direct Buf
场景。我有一个图表,我可以使用右键单击来执行平移。这非常有效。然后我完美地添加了右键菜单。 问题。现在,即使在拖动操作完成后释放鼠标,也会显示右键菜单。 有没有办法在 Java Swing 或 Jav
我使用此代码获取 ABPerson 的姓氏 CFStringRef lastNameRef = ABRecordCopyValue((ABRecordRef)personRecordRef, kABP
目前,我们在基于 C 的嵌入式应用程序中使用 malloc/free Linux 命令进行内存分配/取消分配。我听说这会导致内存碎片,因为内存分配/取消分配会导致堆大小增加/减少,从而导致性能下降。其
当我尝试释放缓冲区时遇到问题。每次我尝试将缓冲区传递给释放方法时,都会发生段错误。 Valgrind 确认段错误位于 BufferDeallocate 方法中。 ==30960== Memcheck,
我想知道何时按下或释放修改后的键(Ctrl 或 Shift)。 基本上,用户可以在按下修改键的情况下执行多次击键,而我不想在它被释放之前执行一个操作(想想 Emacs 和 Ctrl + X + S).
我编写了一个相当大的网络应用程序。它运行良好一段时间,然后慢慢开始运行缓慢,因为 DOM 节点开始爬升到 80,000 - 100,000 左右。 所以我一直在 Chrome 开发工具控制台 (DCT
我知道在像 c 这样的语言中,我需要在分配内存后释放它。 (我来自 Java),对此我有几个问题: 当我在做的时候: int array[30]; (即创建一个大小为 30 个整数的数组)与
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How to release pointer from boost::shared_ptr? Detach
我有一个可以从多个后台线程访问的类,可能同时访问。我无法复制该类,因为重新创建它的内容(处理或内存方面)可能很昂贵。 也有可能在后台处理仍在继续并访问该属性时替换了此类的属性。 目前我有定期的保留/释
这个问题是对: 的扩展链接-1:Creating an image out of the ios surface and saving it Link-2:Taking Screenshots fro
我有一个实例变量 NSMutableArray* searchResults。 首先,我初始化它: self.searchResults = [[NSMutableArray alloc] init]
如果我在堆上声明一些东西,比如 char *a=new char[1000] 并且主程序停止,如果没有 delete[]<,那么分配的内存会发生什么 调用?它保留在堆上还是自动释放? 最佳答案 就C+
在开发相机应用时,我遇到了一个异常,该异常仅在我切换到其他应用时发生(onPause() 用于我的应用)。 01-15 17:22:15.017: E/AndroidRuntime(14336): F
使用 JDK 1.8 编译时出现 maven 编译器错误 无法执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (de
将 BufferedImage 保存到磁盘(以释放内存)的最快方法是什么? 我的 Java 应用程序处理大量图像(每约 300 毫秒将图像加载到内存中)。大多数这些图像都会立即被丢弃 (gc),但每隔
使用 JDK 1.8 编译时出现 maven 编译器错误 未能在项目 DUMMY 上执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:
我是一名优秀的程序员,十分优秀!