一起使用 "new" 和 "if" 语句 - 语法相关

Using "new" and "if" statements together - syntax related

对不起大家。我的意思是在我发布的代码中有一个星号。请重新回答。

我正在为同事做代码审查,我看到弹出以下语句:

if ((someClass *object1 = new someClass))
{
    // Do work
}

这个说法和下面的说法一样吗?

someClass *object1 = new someClass;
if (object1)
{
    // Do work
}

我只是想看看它们是否相等,这样我们就不会遇到任何错误。

您不能在第一种形式的 if 条件内创建对象,除非类型立即出现在括号内,因此:

if (someClass* object1 = new Someclass(...)) { ... }

或者,一般来说:

if (someType object1 = whatever) { ... }

if (someType object1{...constructor args}) { ... }

撇开语法细节不谈——主要区别在于上面的形式使用 if 范围来控制

  • object1变量的生命周期 - 当if终止时将调用析构函数(这可能很重要,如果你的变量的控制资源,但指针无论如何都没有析构函数,因此您需要确保在 if 范围完成之前调用 delete - 请考虑使用智能指针)和

  • object1 标识符本身,它可以在封闭范围内自由地用于一些其他不相关的变量。

在你的第二种形式中,变量保留在 if 范围之后的范围内,并且标识符在它所在的范围结束之前不能被重用。

new 的默认行为是如果不能 return 指向新分配内存的指针则抛出异常,因此 if 语句只会被跳过在这种情况下,使代码等同于:

...
{
    someClass* object1 = new SomeClass;
    // other if content is effectively in a scope here

    // to avoid a leak, must either:
    - delete object1;
    - copy/save the pointer somewhere to delete later 
}
...

奇怪的代码。真的有用吗?

代码中有错误。你应该这样写:

someClass* object1 = new someClass;

此外,我宁愿使用std::unique_ptr来存储内存。

std::unique_ptr<someClass> object1(new someClass);
if (object1)
{
}

看起来两个都不应该编译。假设您的意思是 someClass* object1 = new someClass 那么两者之间的唯一区别是 object1 变量何时超出范围,因此何时需要清理它。当在 if 内时,它超出了 if 的范围,而第二个版本超出了封闭范围的范围。

但 C++ 不是 Java,并且鉴于它是在 if 语句的非常局部范围内创建的,我建议在这里完全避免 new 并只分配它在堆栈上。如果需要控制生命周期,请在{ }中括起来:

someClass object1;
// Do work

最后请注意,默认情况下 new 永远不会 return 0/null 但会抛出异常。因此,原始版本中的 if 检查将无效。

如果 new 失败,它将 return 一个 bad_alloc_exception 你应该在你的程序中捕获。因此,在这种特殊情况下,我看不到 if 存在的目的,因为它就在分配之后。

您的 new 在失败的情况下不抛出 bad_alloc_exception 的一种方法是指定 nothrow:

someClass* object1 = new(nothrow) someClass;

如果失败object1 = nullptr,你可以测试

if (object1 != nullptr)

if ((someClass* object1 = new(nothrow) someClass))

注意第二个版本,因为它在 if 语句结束后将超出范围,因此需要使用 delete.[=22= 在此范围内清理它]

我假设你调用了 set_new_handler() 以避免分配错误抛出 bad_alloc 异常而不是返回 null(默认)。

显示的语法仍然不正确,但可以编译以下内容:

if (someClass *object1 = new someClass)
{
    // Do work
    delete object1; // if you do not, you will have a memory leak 
                    // because object1 goes out of scope on next line
}
// object1 is now out of scope 

someClass *object2 = new someClass;
if (object2)
{
    // Do work
}
// object2 is still in scope and can be used
delete object2;

所以区别仅在于,在第一种语法中,指针在 if 块的末尾超出范围,并且 必须 之前被释放以避免内存泄漏。

之间有细微差别
if ((someClass *object1 = new someClass))
{
    // Do work

    delete object1;
}

object1 = 0; // ERROR!!!!!

someClass *object1 = new someClass;
if (object1)
{
    // Do work

    delete object1;
}

object1 = 0; // OK

第一种情况,object1只能在的作用域块中的条件表达式AND中访问如果。而在第二种情况下,您仍然可以在 if.

之后访问 object1