题
问候,大家好!
检查我自己的代码,我想出了这个有趣的行:
const CString &refStr = ( CheckCondition() ) ? _T("foo") : _T("bar");
现在我完全不知所措,无法理解为什么它是合法的。据我明白,const引用必须被初始化,或者与R值或L值。未初始化的引用不能存在。但()?操作者将其分配值到参考之前执行校验条件()函数。我现在可以看到,在执行校验条件(),refStr存在,但还没有初始化。会发生什么,如果校验条件()将抛出一个异常,或用goto语句将控制权?它会留下参考初始化还是我失去了一些东西?
解决方案
简单的例子:const int x = foo();
此恒定太必须被初始化,并且该foo()
需要被调用。这种情况发生在必要的顺序点:x进入所有脑干只有当foo的返回
要回答你的其他问题:如果foo()
会throw
,异常会被由catch()
某处捕获。对于try{}
的catch()
块包围const int x = foo();
明显。因此const int x
超出范围已经,这是不相关的,它从来没有得到一个值。如果有该异常没有catch
,你的程序(包括const int x
)不见了。
C ++不具有无规goto
的。他们可以foo()
内跳转但是,这并不重要; foo()
仍然必须返回。
其他提示
您失去了一些东西 - 这是完全合法的代码,而事实上这样的代码是有条件的经营者最常见的和最好的应用之一。它总是错误的认为,编译器必须在内部做的事情以相同的顺序,代码奠定了在页面上 - 这是完全可以自由地评估条件运算符(这是justv另一种表达),然后根据结果执行初始化。
作为一个goto,没有在一个初始化使用一个的方式。并且如果有异常抛出,参考被认为从来没有在第一时间被创建。
未初始化的引用不能存在。
不幸的是有趣的事情可以在初始化过程中进行。你可能还写了
const int& a = foobar(a) ? 1 : 2;
或用于物质
const int& a = a;
我想,因为编译器进行从左到右,一个确实是在右侧的范围,所以的技术上的你应该能够使用它充其量它可以提醒:
“ComeauTest.c”,第9行:警告:变量 “a” 被设定其值之前使用
const int& a = foobar(a) ? 1 : 2;
^
自然地,这只能导致未定义的行为与使用任何未初始化的变量。
您的例子是很好的,因为你不使用它引用已初始化之前。
我现在可以看到,在执行校验条件(),存在refStr,但仍然没有被初始化。
从一个语言律师点,这是错误的。在初始化过程中,refStr
还不存在。我猜你的可视化调试器是给你误导性的提示。
如果在初始化中的代码导致错误条件,refStr
将不存在,并且永远不会已经存在。
这是完全合法的。任一这成功完成与参考绑定到一个有效的对象或抛出异常,并且控制块外转移和参考不再在范围从而没有人的它关心了。
这是例外,将带您到一个地方,refStr是无法访问的,你不能去一个地方,它是从那里。 goto语句将无法脱身校验条件(),如果它是一个功能,您将无法使用goto语句,如果它是一个宏。一个longjmp的()将作为例外同样的效果:你会去一个地方,那里refStr是无法访问