关于C++的一点疑惑
#include <iostream>
using namespace std;
struct A{
static int x;
int y;
int z;
public:
operator int(){return x-y;}
A operator ++(int){return A(x++,y++);}
A(int x=1,int y=2){A::x=x;A::y=y;}
};
int A::x=23;
int main()
{
int i;
A a(4,3);
cout<<"a.x"<<a.x<<" a.y"<<a.y<<endl;
i=a++;
cout<<"a.x"<<a.x<<" a.y"<<a.y<<endl;
return 0;
}
输出为 a.x4 a.y3
a.x4 a.y4
对这段代码的输出不理解,望高手指点。
[解决办法]
理一下逻辑:
1、A a(4,3); 会调用构造函数相信你明白,会把X赋值为4,Y赋值为3.注意此处的X为静态变量,它不属于任何一个对象,它是共享的,也就是说无论你构造多少个对象,内存中只此一份。
2、i=a++; 会调用A operator ++(int){return A(x++,y++);}
3、调用构造函数时的值传递 函数值传递,相当于赋值操作,调用构造函数时实参赋值给形参的具体操作应该是x=x++,y=y++,左值的x为4,左值的y为3,而右值的x为5,右值的y为4。
4、构造构造调用 这里就需要注意了,这儿会生成一个新的对象,因为调用了A的构造函数,我们姑且叫作生成这个对象为b,由于X的值是共享的,所以b可以改变X的值,A::x = 4,所以X的值为4,但是A::y = y这个就改变不了y的值了,这儿的赋值,意思是b.y = 3,而对象a.y的值当然没变仍然是4.
PS:其实i=a++这句不好,一般情况下,这种不太能预知结果的表达式应该避免,给i赋值对这段程序来说没有什么意义,倒不如写成a++。如果LZ将这句改成A b = a++;你再输出b.x b.y的值,相信LZ就会明白了。
[解决办法]
1楼说得不对,静态成员是可以改变的。如果不允许改变的话,编译时就通不过。
问题出在A operator ++(int){return A(x++,y++);} 这个函数实际上有两个操作。
先是x++和y++。做完这个操作,a.x(也就是A::x)的值被改成了5,但是a.x原先的值被放在一个临时变量temp_x里,这个temp_x的值是4。
然后调用A的构造函数A(temp_x,temp_y),也就是A(4,3),把temp_x又写回了A::x,抹掉了前一步写的值5。
所以不是A::x的值没变,而是变了以后又变回来。
6楼前面说得对,最后一句有问题。无论写成A b=a++,还是直接写成a++,结果都一样,因为问题出在a++里面,而不是赋值时出的问题。