运算符<<函数的返回值
Return value of operator<< function
我知道我应该从"operator<<"返回"ostream&",以便能够像这个一样"链式"运算符
cout<<a<<b<<c;
然而,在下面的代码中,我没有返回"ostream&",并且链接仍然是可能的。为什么?
#include <iostream>
using namespace std;
class CComplexNumber{
float m_realPart;
float m_imagPart;
public:
CComplexNumber(float r,float i):m_realPart(r),m_imagPart(i){}
friend ostream& operator<<(ostream& lhs,CComplexNumber rhs){
lhs<<"["<<rhs.m_realPart<<","<<rhs.m_imagPart<<"]"<<endl;
//MISSING RETURN STATEMENT!
}
};
int main() {
CComplexNumber a(1,2);
CComplexNumber b(3,4);
CComplexNumber c(5,6);
cout<<a<<b<<c;
return 0;
}
输出
[1,2]
[3,4]
[5,6]
从非void函数的末尾脱落是未定义的行为。一种可能的未定义行为是,如果返回到位,它将按预期工作。
g++提供了一个方便的警告,以防止这种情况发生在你身上。
如果您对它为什么在这种情况下工作感兴趣,您应该查看生成的程序集。我的即兴猜测是,指向lhs
的指针留在了寄存器中,该寄存器在您的平台上返回值。由于C++中的引用通常是用指针实现的,这将具有与向lhs
返回引用相同的效果。
但这完全是在黑暗中捅刀子,最终并不是很有趣或重要。只要听编译器的警告,不要那样做。
这是"纯粹的运气"。函数的返回值在特定的寄存器中。由于您现有的代码已经调用了operator<<
,因此它会为您返回正确的内容,因此只要在该点之后不涉及其他代码,您就可以从operator<<
的内部级别获得返回值。添加一个std::string s = "xyz";"
(并在代码中的某个位置使用s
),它可能会中断,因为在函数末尾调用的std::string
的析构函数"破坏"了operator<<
的返回值。因此,依赖它是非常危险的,因为无害的变化会导致它"崩溃"。
相关文章:
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 如何从 std::thread 返回值
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- 方法错误"not all control paths return a value"和方法不返回值
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 对fread的返回值感到困惑
- 程序不向函数返回值
- 如何在另一个函数中使用返回值作为参数?
- 如何使用 uint64_t 键类型从 std::map<int, std::string> 返回值?
- 使用 std::p air 进行返回值优化
- C++输出参数与返回值