zoukankan      html  css  js  c++  java
  • C和C++区别——前置自增与后置自增

    一、先看下面两段完全一样的代码块

    /* test.cpp */
    int main()
    {
        int a = 5;
        ++a = 7;
        printf("%d
    ", a);
        return 0;
    }
    /* test.c */
    int main()
    {
        int a = 5;
        ++a = 7;
        printf("%d
    ", a);
        return 0;
    }

      在test.cpp文件与test.c文件下会分别显示什么呢?运行结果显示,在test.cpp下打印出 7 , 而在test.c下编译出错,报错信息:

    二、前置自增

      乍一看++a = 7; 这条语句很奇怪,本以为会在C++里编译报错,没想到居然成功输出了7。

      学过C一定对前置自增“先+1,再返回”的操作很熟悉了,++a 会对a值先+1,再返回a当前的值(也就是6),注意在C里返回的是“值”(value)而不是 “引用”(reference),因此在test.c中 ++a = 7; 由于++a返回的是6这个右值,因此也就不能作为=的左操作数。

      而在C++里由于加入了引用这个概念,因此,++a会先对a值+1,再返回a的引用(是一个左值)。因此在C++标准中对于前置自增的运算符重载操作返回的也是 Object& 而不是 Object。

    三、后置自增

      相对于前置自增,后置自增的操作是“先返回当前值,再+1”,也即 a++ 执行的是 int tmp = a; ++a; return tmp; 后置自增无论在C里还是C++里返回的都是值(Value),因此在后置自增上并没有太大的区别。由于后置自增返回的是值(Value),因此对于a++ = 7;这条语句,不论是在C++还是C中都会编译报错的。

      说到这可能有人会想到,既然C++里加入的引用可以作为前置自增的返回类型,为什么后置自增的返回不用引用呢?

      (1)首先,a++ <==> { int tmp = a; ++a; return tmp;  } ,tmp是一个临时变量,无法返回其引用。

      (2)在C++ Primer中明确说明了,C++中前置自增返回的是引用,后置自增则将对象原始值的副本作为右值返回既然要作为右值返回,后置自增的运算符重载的返回类型 就应该是 const Object,这样对于任何一个以 const Object作为返回类型的后置自增运算符重载,类似于 a++ = 7这样的语句都会报错,也即 a++返回了一个右值(rvalue)

    四、运算符重载示例

      关于前置++后置++的重载,详细可查<<More Efficitive C++ >> 条款6;

    class A {
    public:
        A(int a) : m_data(a) {}
    
        A& operator++(){ //前置自增,返回 Object &
            m_data += 1;
            return *this;
        }
    
        const A operator++(int) {   //后置自增, 返回 const Object ,右值
            A tmp(m_data);
            ++*this;
            return tmp;
        }
    
        A& operator=(const A& a) {
            this->m_data = a.m_data;
            return *this;
        }
    //private:
        int m_data;
    };
    
    /* test.cpp */
    int main()
    {
        A a(5);
        A b(10);
        ++a = b; // ++a返回a本身,>> a.m_data = 10;
        cout << a.m_data << endl;
        cout << (b++).m_data << endl; // b++返回tmp副本作为右值,>> 10
        //(b++) = a;  //error, b++返回的是右值
    
    }

    五、参考

      <<More Efficitive C++ >> 条款6;

      <<C++ Primer 5th 中文版>> 4.5 递增和递减运算符 

      

  • 相关阅读:
    js学习(六)--作用域
    js学习(五)--函数function()、for...in、函数中的方法,arguments
    js学习(四)-- 数据类型、基本数类型的包装类、js的对象、toString、构造方法、原型对象
    js自学(三)-- js的语句代码块&流程控制语句(if,while,break等)
    自学js(二)--强制类型转换&运算符(操作符)
    java的hashcode和equals
    sprinboot---读取配置文件(application.yml)中的属性值
    springboot打包为jar包后怎么在外部修改配置文件
    bat脚本编写--启动springboot服务
    关于clean报错问题 Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-
  • 原文地址:https://www.cnblogs.com/GuoYuying/p/13820500.html
Copyright © 2011-2022 走看看