C++类的问题,输出结果

//X.h
class X{
	public:
		int f1();
		int f2();
	protected:
	    int m; 
};
//X.cpp
int X::f1()
{
	int m = 5;
	cout<<"f1: m = "<<m<<endl;
	return m;
 } 
int X::f2()
{
	int m=3;
	cout<<"f2: m = "<<m<<endl;
	return m;
}
//main.cpp
int main()
{
    X x;
    cout<<x.f1()<<x.f2();
	return 0;
}

为什么输出结果是

f2: m = 3

f1: m = 5

53

而不是

f1: m = 5

f2: m = 3

53


hc茶
浏览 1604回答 4
4回答

onemoo

其实这两种结果都有可能出现。先明确一下关于运算符和操作数的基本知识:运算符需要有操作数才能构成表达式(比如 a + b 就是一个加法表达式,+ 是运算符,a 和 b 就是操作数)。而运算符表达式在执行时有一个“操作数求值”的过程(也就是确定 a 和 b 的值)。如果操作数本身是个函数调用,那么对这个操作数求值就是得到函数的返回值。有一点很重要:函数中的一些代码(尤其是 cout << 这样的IO操作)的行为算是函数的副作用,这些副作用的发生并不一定和求值同时发生。关于表达式的副作用何时发生,C++ 其实有比较复杂的序列点规则。我不打算细说这个规则,后面遇到具体情况时我会提到它,你目前只需要记住副作用不一定和求值同时发生。那么我用你的这个例子具体说明一下:cout<<x.f1()<<x.f2() 这是一个复合表达式。对其中的 cout << x.f1() 这个子表达式来说 x.f1() 是右操作数,这个右操作数是个函数调用。而 << 其实也是函数调用,这是重载 << 运算符函数。x.f1() 其实算是 << 函数的参数。cout<<x.f1()<<x.f2() 其实是连续两次 << 调用,并且是 <<x.f1() 在前,<<x.f2() 在后(运算符的优先级决定的)。也就是说一定是先调用了 << 5,再调用 << 3,所以最后结果是 53(5在3之前)。至于让你疑惑的那部份输出:C++ 的求值和序列点规则说“参数的副作用要在函数执行前发生”。注意:只是在之前发生即可。所以完全有可能 f1() 和 f2() 的副作用(也就是输出"f1: m = 5"和"f2: m = 3")在两次 << 函数调用前就已经发生了。加之 C++ 没有规定参数副作用谁先谁后,所以"f2: m = 3"先输出是有可能的。====以上就是关于你看到的这个结果的解释====下面我想多说下:我不知道你用的编译环境是什么? 编译器遵循的是哪个标准?实际上如果你用的编译器支持的 C++ 标准够新的话(C++17),f1: m = 5 和 5 是会先输出的。这是因为在 C++17 标准中增加了一些序列点规则,导致这个代码的行为不再是不确定的,而是保证会先输出 f1: m = 5 和 5。(我有些好奇不同编译器在各个标准下的行为,希望能告知我你用的编译环境是什么)最后,你知道你其实根本就没用到 X 的成员变量 m 吧...

___C___

cout是先从右到左分别运行函数f2(),f1(),然后再输出两个函数的return返回值,谢谢采纳

慕设计7118955

cout输出将输出先像压栈一样保存在缓冲区,在进行输出,所以是先运行右边再左边
打开App,查看更多内容
随时随地看视频慕课网APP