对不起大家。我的意思是在我发布的代码中有一个星号。请再次回答。
我正在为同事进行代码审核,我看到以下语句弹出:
if ((someClass *object1 = new someClass))
{
// Do work
}
此声明是否与以下内容相同?
someClass *object1 = new someClass;
if (object1)
{
// Do work
}
我只是想看看他们是否平等所以我们不会得到任何错误。
答案 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 ,如果。