【问题标题】:NULL in instantiation实例化中的 NULL
【发布时间】:2011-06-12 07:51:19
【问题描述】:

在编写 C++ 时,我们假设以下代码行:

Object* obj = new Object(); 

如果此行既编译又不会导致异常或任何其他可见的 运行时问题,obj 可以在这行执行后立即为 NULL 吗?

【问题讨论】:

    标签: c++ null


    【解决方案1】:

    不,obj 不能是 NULL

    如果new 失败,它将抛出std::bad_alloc 异常。如果没有抛出异常,obj 保证指向一个完全初始化的 Object 实例。

    new 的变体不会引发异常

    Object *obj = new(nothrow) Object();
    

    在这种情况下,如果new 失败,obj 将变为NULL,并且不会抛出std::bad_alloc 异常(尽管Object 的构造函数显然仍然可以抛出异常)。

    在一些较旧的编译器上,new 可能不会抛出异常,而是返回 NULL,但这不是符合标准的行为。

    如果您重载了 operator new,它的行为可能会有所不同,具体取决于您的实现。

    【讨论】:

    • 或者除非你做过类似#define new new(nothrow) 的操作? ;)
    • @Karl Knechtel:这是未定义的行为
    • 无异常编译会发生什么?它会自动使用 nothrow 版本吗?
    • @Tamás:通过链接查看@littleadv 的答案。
    【解决方案2】:

    不,您的确切行不能那样做。如果没有抛出异常,obj 将始终指向有效内存。但是,如果无法分配内存,则以下行将返回 0

    Object* obj = new (std::nothrow) Object();
    

    【讨论】:

      【解决方案3】:

      new throws std::bad_alloc 是分配不成功。所以你应该抓住那个异常。
      如果你想在new. 之后检查NULL,你应该使用 nothrow new

      【讨论】:

        【解决方案4】:

        不,除非您禁用异常或重载 std::new 以执行标准异常以外的操作(失败时抛出 std::bad_alloc)。

        (我不确定std::new 在禁用异常时的行为,但可以对此进行讨论here...)

        【讨论】:

        • 该标准没有定义禁用异常时 new 的行为方式,因为该标准没有定义可以禁用异常的世界。这取决于每个单独的编译器实现。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        • 2016-07-13
        • 1970-01-01
        相关资源
        最近更新 更多