使用" new"和"如果"语句在一起 - 语法相关

时间:2015-01-23 14:55:00

标签: c++ if-statement new-operator

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

我正在为同事进行代码审核,我看到以下语句弹出:

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

此声明是否与以下内容相同?

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

我只是想看看他们是否平等所以我们不会得到任何错误。

6 个答案:

答案 0 :(得分:6)

除非类型直接显示在括号内,否则无法在第一种形式的if条件内创建对象,因此:

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

或者,一般来说:

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

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

除了语法细节之外 - 主要区别在于上述表单使用if范围来控制

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

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

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

new的行为默认是如果它不能返回指向新分配的内存的指针则抛出异常,因此在这种情况下只会跳过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 
}
...

答案 1 :(得分:2)

奇怪的代码。它真的有效吗?

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

someClass* object1 = new someClass;

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

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

答案 2 :(得分:1)

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

但是C ++不是Java,并且鉴于它是在if语句的本地范围内创建的,我建议完全避免使用new并将其分配到堆栈中。如果您需要控制生命周期,请加入{ }

someClass object1;
// Do work

最后请注意,默认情况下new永远不会返回0 / null但会引发异常。因此,检查原始版本将无效。

答案 3 :(得分:1)

如果new失败,它将返回您应该在程序中捕获的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在此范围内进行清理。

答案 4 :(得分:0)

我假设您调用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块末尾的范围,必须才被释放,以避免内存泄漏。

答案 5 :(得分:0)

之间存在细微差别
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 只能在 if 的作用域块中的条件表达式 AND 中访问。在第二种情况下,您仍然可以在之后访问 object1 ,如果