管理 C++ 构造函数中的 bad_alloc 异常

2024-05-28

我有 Java 经验,最近正在做一些 C++ 编码。我的问题是,如果我有类 A,我必须将类 B 和类 C 实例化为 A 的两个成员变量。

如果在 A 的构造函数中,我是否应该假设类 B 和 C 的分配永远不会失败,并在 A 的析构函数中处理错误分配异常?

如果我不做这个假设,也就是说我添加了一些try catch块来捕获B类和C类的bad_alloc,那么如果发生分配异常,我应该在A的构造函数中进行清理吗?

推荐的做法是什么?如果“new”产生错误的分配,那么指针携带什么值?


如果在构造 A 期间抛出异常,您的析构函数将not叫做。

显然,解决方案取决于您正在做什么,但理想情况下您不会have进行任何清理工作。你应该利用RAII http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization,你的班员应该自己清理。

也就是说,不要使用任何原始指针;把它们包起来,让包装纸来处理。惊喜! C++ 程序员和你一样讨厌内存管理。我们喜欢把它包起来然后忘记它。

不过,如果你确实需要的话,我认为这是常见的:

struct foo
{
    int* i;
    some_member_that_could_throw crap;

    foo() // do *not* new i! if the second member throws, memory is leaked.
    {     // rather:

        // okay we made it, the other member must have initialized
        i = new int;
    }
};

对于您的指针,它的值保持不变。什么时候new抛出异常(无论出于何种原因),堆栈将被展开。表达式的其余部分被放弃。


以下是异常和对象创建的工作原理。这是一个递归过程,因为每个成员或基类将依次遵循此列表。基本类型没有构造函数;这是递归的基本情况。

  1. 首先,构造我们的每个基类。 (反过来又运行这个列表。)
  2. 一一初始化类的成员。
  3. 运行构造函数主体。
  4. 以一个完全构建的对象完成。

显然,如果第 1 项失败,我们不需要做任何清理工作,因为我们的成员都没有被初始化。我们那里很好。

二是不同。如果在任何时候其中一个无法构造,则初始化的成员so far将被破坏,然后构造函数将停止进度,并且异常会以愉快的方式继续。这就是为什么当您让您的成员自行清理时,您无需担心。未初始化的无事可做,而已初始化的将运行其析构函数,并在其中进行清理。

三者更是如此。现在您的对象已完全初始化,您可以保证它们都将运行其析构函数。再说一次,把事情包起来,你就没什么可担心的了。However如果你有一个原始指针,那么就需要使用 try/catch 块:

try
{
    // some code
}
catch (..) // catch whatever
{
    delete myrawPointer; // stop the leak!
    throw; // and let the exception continue
}

在没有 RAII 的情况下编写异常安全代码要混乱得多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

管理 C++ 构造函数中的 bad_alloc 异常 的相关文章

随机推荐

  • SPGridView、数据以及确保数据安全的正确方法

    我正在使用 SPGridView 来呈现一些数据 并启用了效果很好的过滤功能 直到您选择数据中的特定项目进行过滤 有问题的数据项在字符串中包含撇号 例如 这是 richards 的字符串 这会导致后过滤器应用程序页面加载因错误而终止 Syn
  • 在Java Servlet中获取通过jquery ajax发送的参数[重复]

    这个问题在这里已经有答案了 我在网上搜索这个主题 但找不到有效的示例 我会很高兴有人能给我帮助 这就是我测试的 ajax url GetJson type POST dataType json contentType application
  • 如何为现代 C++ 迭代 JSON 中的 JSON

    我想迭代 json 对象中的每个条目 但我收到一个又一个难以理解的错误 下面的例子如何改正 include
  • 从命令调用操作

    我想通过自定义命令执行操作 Controller php类的forward方法提供了这个功能 但是不知道从命令文件的execute 方法访问它 由于请求堆栈的原因 使控制器成为服务将导致性能开销 因为它应该返回一个HttpResponse
  • Pandas:自定义类作为具有多索引的列标题

    我正在尝试使用对象作为多索引中的列标题 dataframe 但我似乎无法让它工作 eq hash and str 仅适用于简单的数据框 这是一个小例子 class Signal def init self name self name na
  • API Gateway HTTP 代理与 aws-sam 集成(不是 Lambda 代理)

    我正在尝试使用 aws sam 在本地开发 模拟我的 API 网关 我的 API 网关充分利用HTTP 代理集成 https docs aws amazon com apigateway latest developerguide api
  • 获取两个顶点之间的边属性值时出现 ClassCastException

    我正在尝试获取两个顶点之间的边缘属性值并低于异常 java lang ClassCastException 无法将 java lang String 转换为 scala runtime Nothing 环境 内存中的泰坦 Code val
  • QuerySet,对象没有属性id - Django

    我试图在 Django 中获取某个对象的 id 但不断收到以下错误 异常值 QuerySet 对象没有属性 ID 我在views py中的函数 csrf exempt def check question answered request
  • 我们可以在板条箱之间共享测试实用程序吗?

    我有 crate 0 有src lib rs如下 cfg test pub mod test utils pub struct OnlyInTests pub usize pub fn helper gt usize 999 test fn
  • 线程局部变量在销毁期间具有意外值

    我使用 C 17 标准编写了以下代码 std mutex mutex struct Test Test std lock guard lock mutex std cout lt lt Test lt lt a lt lt std endl
  • Linq lambda表达式多对多表选择

    我有三个表 其中两个是多对多关系 Picture 这是中间mm表中的数据 Edit 到这里 我得到正确的 4 行返回 但它们都是相同的结果 我知道我需要返回 4 行 但有不同的结果 return this mediaBugEntityDB
  • 如何使用 go1.6.2 构建 linux 32 位

    有没有任何组合GOARCH and GOOS我可以设置哪些值来构建 ELF 32 位二进制文 件 GOOS linux and GOARCH 386 更多示例 架构 32 bit gt GOARCH 386 64 bit gt GOARCH
  • 默认情况下 dbo 架构中的 EF 6 Code First __MigrationHistory

    我是代码优先实体框架的新手 第一次运行我的应用程序后登录数据库时 当我看到 MigrationHistory 表时 我有点困惑 我现在了解对此表的需求 但不喜欢它位于用户表内的标准 dbo 模式中 我认为它很唐突且有风险 我的第一个想法是将
  • 单击时未调用 UITableView didSelectRowatIndexPath

    非常非常奇怪 它在任何地方都有效 但在这里 void tableView UITableView aTableView didSelectRowAtIndexPath NSIndexPath indexPath MyViewControll
  • 在 LINQ 中确定具有分钟精度的日期时间值的相等性

    我需要使用分钟精度比较两个日期时间值以确定相等 完全相同 这是最好的方法吗 我的日期可能有秒和毫秒 但我只想考虑到分钟 where Math Abs datetime1 Subtract datetime2 TotalMinutes 0 检
  • 让 NUMBERFMT 填充默认值的简单方法?

    我正在使用 Windows API获取数字格式Ex http msdn microsoft com en us library dd318113 28v vs 85 29 aspx使用当前用户的适当本地化选项来格式化一些数字以进行显示 例如
  • 在C中将毫秒转换为秒

    简单的C问题 如何正确 简洁地将毫秒转换为秒 有两个限制 我在这个微小的 C 编译器子集中没有浮点支持 我需要将秒四舍五入到最接近的秒 1 499ms 向下舍入 500 999ms 向上舍入 不需要关心负值 int mseconds 160
  • 如何使用npm安装本地网络中的所有节点模块?

    我的节点应用程序将部署在无法访问互联网的银行中 我可以将所有节点模块下载到本地目录中并从中安装它们 还是将node modules复制到银行机器上 任何安全实用的建议将不胜感激 谢谢 OR 如何添加node modules不使用依赖项int
  • 如何在不影响背景内容的情况下弯曲底部导航栏角?扑

    我创建了一个带有颤动的自定义底部导航栏 但我仍然可以看到白色填充了弧角后面的背景 我想看看背景内容 这就是底部导航栏的样子 正如你所看到的 角落里充满了白色 这是我的底部导航栏代码 bottomNavigationBar Container
  • 管理 C++ 构造函数中的 bad_alloc 异常

    我有 Java 经验 最近正在做一些 C 编码 我的问题是 如果我有类 A 我必须将类 B 和类 C 实例化为 A 的两个成员变量 如果在 A 的构造函数中 我是否应该假设类 B 和 C 的分配永远不会失败 并在 A 的析构函数中处理错误分