C++ 使用;新";及;如果;语句一起-语法相关
大家都很抱歉。我的意思是在我发布的代码中有一个星号。请再次回答。 我正在为一位同事进行代码审查,我看到弹出以下语句:C++ 使用;新";及;如果;语句一起-语法相关,c++,if-statement,new-operator,C++,If Statement,New Operator,大家都很抱歉。我的意思是在我发布的代码中有一个星号。请再次回答。 我正在为一位同事进行代码审查,我看到弹出以下语句: if ((someClass *object1 = new someClass)) { // Do work } 该声明是否与以下内容相同 someClass *object1 = new someClass; if (object1) { // Do work } 我只是想看看它们是否相等,这样我们就不会有任何错误。除非类型立即出现在括号内,否则无法在第一种
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
标识符本身,可以在封闭范围内自由地用于其他一些不相关的变量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
}
...
奇怪的代码,真的有用吗 代码中有一个错误。您应该这样编写:
someClass* object1 = new someClass;
此外,我更愿意使用std::unique\u ptr来存储内存
std::unique_ptr<someClass> object1(new someClass);
if (object1)
{
}
std::unique_ptr object1(新的someClass);
如果(反对1)
{
}
看起来两个都不应该编译。假设您的意思是someClass*object1=new someClass
,那么两者之间的唯一区别是object1
变量超出范围,因此需要清理它。当if
在if
内部时,它与if
一起超出范围,而第二个版本超出了封闭范围
<>但C++不是java,并且假定它是在<代码>的本地范围内创建的,如果语句,我建议完全避免<代码> < <代码> >,并将其分配到堆栈中。如果需要控制生存期:,请在<代码> {}} /代码>中加入。
someClass object1;
// Do work
最后请注意,默认情况下,
new
不会返回0/null,而是抛出一个异常。因此,原始版本中的if检查将无效。如果new
失败,它将返回一个您应该在程序中捕获的错误分配异常de>如果
存在,因为它就在分配之后
如果出现故障,您的新
不抛出错误分配异常
的一种方法是指定nothrow
:
someClass* object1 = new(nothrow) someClass;
如果出现故障,您可以测试
if (object1 != nullptr)
或
请小心使用第二个版本,因为在关闭
if
语句后,它将超出范围,因此需要使用delete
在此范围内清理它。我假设您调用了set\u new\u handler()
为避免分配错误,抛出错误分配
异常,而不是返回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!!!!!
及
在第一种情况下,object1只能在if的作用域块中的条件表达式和中访问。而在第二种情况下,您仍然可以在if之后访问object1。我认为,“new”会在失败的情况下抛出异常(bad_alloc exception)。多余的括号用于禁用来自GCC的警告(和Clang)关于条件函数中的赋值。主要的区别确实需要强调,因为这是关于范围的大联盟差异!@RichardChambers在理论上是的,但在实践中……如果范围结束是一个问题,那么你可能在函数中做了太多。而在流控制语句中嵌入定义肯定会出现“这是在混淆的标题下。”詹姆士坎茨,我只是要求托尼D强调范围问题,这在他的原始帖子中并不容易看出。他更新并扩展了他的原始帖子,现在这更有用了。@RichardChambers,我理解。但是,伊姆霍,可读性问题更重要。是的,我有麻烦。是的这样写,我在发帖时犯了一个错误。
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