第39课 逗号操作符的分析
1. 逗号操作符(,)
(1)逗号表达式用于将多个子表达式连接为一个表达式
(2)逗号表达式的值为最后一个子表达式的值
(3)逗号表达式的前N-1个子表达式可以没有返回值
(4)逗号表达式按照从左向右的顺序计算每个子表达式的值
exp1,exp2,exp3,…,expN;
【实例分析】逗号表达式的示例 39-1.cpp
#include <iostream> using namespace std; void func(int i) { cout << "func(): i = " << i << endl; } int main() { int a[3][3] = { (0, 1, 2), //注意这里是逗号,不是花括号 (3, 4, 5), //相当于只给数组前三个元素赋值 (6, 7 ,8) //分别是2、5、8,其余为0 }; int i = 0; int j = 0; while (i < 5) func(i), //这里与下一行的i++组合一个表达式 i++; //所以while不会死循环 for(int i=0; i<3; i++) { for(int j=0; j<3; j++) { cout << a[i][j] << endl; //2,5,8,0,0,0,0,0,0 } } (i, j) = 6; //合法:逗号表达式返回j,相当于j = 6 cout << "i = " << i << endl; //5 cout << "j = " << j << endl; //6 return 0; }
运行结果:
2. 重载逗号操作符
(1)在C++中重载逗号操作符是合法的
(2)使用全局函数对逗号操作符进行重载
(3)重载函数的参数必须有一个是类类型(因为这里指的是类的操作符重载)
(4)重载函数的返回值类型必须是引用
ClassType& operator ,(const ClassType& a, const ClassType& b) { return const_cast<ClassType&>(b); //返回右操作符,必须强制转换 }
【编程实验】重载逗号操作符 39-2.cpp
#include <iostream> using namespace std; class Test { int mValue; public: Test(int i){mValue = i;} int value(){return mValue;} }; //利用全局变量来重载逗号操作符 //1、参数必须有一个为类类型 //2、返回值必须为引用 Test& operator ,(const Test& a, const Test& b) { return const_cast<Test&>(b); //强制转换 } Test func(Test& i) { cout << "func(): i = " << i.value() << endl; return i; } int main() { Test t0(0); Test t1(1); //因重载操作符的本质相当于函数调用,所以 //相当于Test tt = operator,(func(t0(0)), func(t1(1)));//函数调用! //当进入函数体,参数的值必须被计算,而两个参数func(t0(0))和func(t1(1)) //的计算次序是不确定的,在g++编译下,输出 //func(): i = 1 //func(): i = 0 Test tt = (func(t0), func(t1)); //逗号表达式,本意是从左向右计算 cout << tt.value() <<endl; //1,虽然结果是正确的,但中间的计算过程与 //逗号表达式原义从左向右计算要求有可能不一致。 return 0; }
运行结果:
3. 重载时出现的问题与本质分析
(1)C++通过函数调用扩展操作符的功能
(2)进入函数体前必须完成所有参数的计算
(3)函数参数的计算次序是不定的
(4)重载后无法严格从左向右计算表达式,不重载时返回能从左向右,所以重载逗号操作符完全无意义。
4. 小结
(1)逗号表达式从左向右顺序计算每个子表达式的值
(2)逗号表达式的值为最后一个子表达式的值
(3)操作符重载无法完全实现逗号操作符的原生意义(从左向右计算)
(4)工程开发中不要重载逗号操作符