第39课 逗号操作符的分析

1、逗号操作符

    1.1、 逗号表达式用于将多个子表达式连接为一个表达式
    1.2、 逗号表达式的值为 最后一个子表达式的值
    1.3、 逗号表达式的 前N-1个子表达式可以没有返回值
    1.4、 逗号表达式按照 从左向右的顺序 -> 计算每个子表达式的值 exp1,exp2,exp3,…, expN ;

  
   /******************* 逗号表达式的示例 *******************/
#include <iostream>
using namespace std;
void func(int i)
{
    cout << "func(int i): i =" << i << endl;
}
int main()
{   //这里因为数组里面的二维使用的不是{},而是逗号表达式,相当于只给数组的前三位赋值:2, 5, 8, 其余为0;改正应该是{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};从左向右的顺序。
    int a[3][3] = {(0, 1, 2), (3, 4, 5), (6, 7, 8)};
    
    int i=0;
    int j=0;
    
    while(i<5)
        func(i),    //这里相当于while(i<5){func(i); i++;}  两句组合成一个表达式。
    i++;
    
    for(i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {               //字符用引号标注,实际的数字直接打印。
            cout << "a[" << i << "][" << j << "]" << a[i][j] << endl;
        }    
    }
    
    (i, j) = 6;     //因为逗号表达式从左向右返回最后一个元素的值。
    
    cout << "i = " << i << endl;    //3
    cout << "j = " << j << endl;    //6
    
    return 0;
}


2、重载逗号操作符

    2.1、在C++中重载逗号操作符是合法的
    2.2、使用全局函数对逗号操作符进行重载
    2.3、 重载函数的 参数必须有一个是 类类型 (因为这里指的是类的操作符重载)     
    2.4、 重载函数的 返回值类型必须是引用

ClassType& operator ,(const ClassType& a, const ClassType& b)
{
    return const_cast<ClassType&>(b); //返回右操作数,要被赋值必须强制转换,去除引用的const属性
}

/************************     重载逗号操作符     ************/
#include <iostream>
using namespace std;
class Test
{
    int mValue;
public:
    Test(int i) //初始化构造函数
    {
        mValue = i;
    }
    
    int value()
    {
        return mValue;
    }
};
/*      //不重载时从左向右正确执行
Test& operator , (const Test& a, const Test& b)
{
    return const_cast<Test&>(b);     //返回最右边的操作数,因为要赋值,所以去除const属性。
}
*/
Test func(Test& i)      //传进来的是对象的‌引用,打印这个对象的值
{
    cout << "func(): i =" << i.value() << endl;
   return i;//仔细测试返回引用和对象的区别,返回引用不会调用拷贝构造函数。
    //传进来时是引用,返回时是对象,则会拷贝一个临时对象存储。
}
int main()
{
    Test t0(0);
    Test t1(1);     //调用构造函数,初始化里面的值mValue
    
    //因重载操作符的本质相当于函数调用,Test tt = operator,(func(t0), func(t1)),进入函数体之前,参数的值必须先被计算出来。而函数的两个参数计算次序是不定的。g++下输出:
    
   Test& t5 = t0;
    func(t1);
    cout << "qqqq" << endl;
    //因重载操作符的本质相当于函数调用,Test tt = operator,(func(t0), func(t1)),进入函数体之前,参数的值必须先被计算出来。而函数的两个参数计算次序是不定的。g++下输出:

    Test tt = (func(t0), func(t1));//逗号表达式的本意为从左向右计算。引用初始化对象,调用拷贝构造函数。

    cout << tt.value() << endl; //虽然结果正确,但中间的计算过程与逗号表达式原义从左向右计算要求可能不一致。

    
    return 0;
}


3、重载时出现的问题与分析

    3.1、 C++通过 函数调用 扩展操作符的功能
    3.2、 进入 函数体前必须完成所有参数的计算
    3.3、 函数参数的计算次序是不定的
    3.4、 重载后 无法严格从左向右 计算表达式,不重载时返回能从左向右,所以 重载逗号操作符完全无意义


4、小结

    4.1、 逗号表达式 从左向右顺序 计算每个子表达式的值
    4.2、 逗号表达式的值为 最后一个子表达式的值
    4.3、 操作符重载 无法完全实现逗号操作符的原生意义 (从左向右计算)
    4.4、 工程开发中 不要重载逗号操作符
    





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值