c++ - 使用标准 C++98/03 干净地分配和构建一个对象

标签 c++

在我的代码中,我需要动态分配和构造一个对象,并将指向它的指针推送到一个 vector 中。在不使用所有那些丑陋的 try-catch block 的情况下,是否有比下面的代码更简洁的方法?我不能使用非标准库。没有 C++11。我只有标准的 C++98/03。

void insert() {
            //...do something...
            MyType* obj = 0;
            try {
                obj = alloc.allocate(1); // yes, even the allocation must be inside one try-catch in my case, since I need to undo something
                alloc.construct(obj, default_obj);
                try {
                    v.push_back(obj);
                } catch (...) {
                    alloc.destroy(obj);
                    throw;
                }
            } catch (...) {
                //..undo something..
                if (obj)
                    alloc.deallocate(obj, 1);
                throw;
            }
}

编辑: alloc 是在某处作为参数传递的分配器,以避免原始新建/删除。 v 是一个 vector 。

最佳答案

显而易见的解决方案是使用自定义 RAII 类:带有重新抛出的 try/catch block 等同于析构函数执行相同的清理,尽管有两个可管理的警告(除非以某种方式使用异常类型):

  • 该对象将没有 catch block 的隐式上下文,即它需要获得传递的必要信息
  • 析构函数总是被调用,即有必要在主操作成功后发出它确实需要做任何事情的信号

由于您没有说明还需要清理什么,除了在析构函数中执行此操作之外,我无法评论如何最好地处理此问题。对于分配器的使用,我实际上会创建一个自定义智能指针,它将构造函数参数和分配器作为参数传递给它自己的构造函数(是的,可变参数和完美转发不可用,这有点烦人但可行:我做了更多类似的事情不止一次)。智能 piinter 实际上也会捆绑分配器,以便稍后使用正确的分配器处理释放。由于如果没有右值引用,移动语义基本上无法正确完成,因此智能指针将使用引用计数。

通常,使用 RAII 是各种隐式撤消的方式,甚至独立于异常:!对于任何不重要的代码,最终都会有人出现并过早地从函数中返回。创建 RAII 类可能需要更多的前期工作,但我发现它极大地使我从与业务逻辑混合的相当技术性的工作中解脱出来。此外,我的许多类一开始都是作为 RAII 类,但后来变成了封装用于访问“资源”逻辑的功能的类。

关于c++ - 使用标准 C++98/03 干净地分配和构建一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9752109/

相关文章:

c++ - 为什么与 printf 未定义行为中的转换说明符不匹配的参数?

c++ - 如何重载作为参数传递给 C++ 模板类的基类方法?

c++ - 为什么我们有类型不匹配?

c++ - OpenGL SDL LINK 错误 MSVCRT.lib

c++ - 防止临时对象的引用传递

c++ - 我可以在成员初始化列表中使用 std::minmax_element 吗?

C++ 重载 : Overloading the [][] operator

c++ - 通过运算符重载写入映射的内容

c++ - 流迭代器的结尾是可配置的吗?

c++ - 检查堆栈中是否存在元素