zoukankan      html  css  js  c++  java
  • c/c++左值和右值

      C/C++中的变量有左值和右值之分,他们的区别主要如下:

    (1)左值可以放在赋值号 = 的左右两边,右值只能放在赋值号 = 的右边

    (2)在C语言中,有名字的变量即为左值;而函数的运行结果或表达式中间变量即为右值

    (3)对于内嵌类型(基本类型,即built-in types),右值是不可以被更改的,也不可以被const,volatile所修饰;

      对于自定义类型,右值却可以通过它的成员函数来进行修改。

    (4)左值也可以作为右值表达式,变量可以是左值,也可以为右值,但常量只能是右值

    (5)右值只能被const 类型的引用所指向;而左值可以被const或非const类型引用指向

    在 c++ 中,每一个表达式都会产生一个左值,或者右值,相应的,该表达式也就被称作“左值表达式”,“右值表达式”。

    例如:

    ++a 为将a进行自加,然后返回a,a本身就有内存地址,为一个左值,因此 (++a)++ 正确;

    而 a++是后自增,在表达式里的值仍然为原来的a,返回a,然后a再被赋值为a+1。而返回的值为一个临时变量,是一个右值,不能被改变,不存在内存地址。所以(a++)++错误。

    //左值只能为变量,不能是常量,因为常量不能放在赋值号左边;但右值可以是变量或常量,因为常量和变量都可以放在赋值号右边。

    #include<iostream>
    using namespace std;
    template<typename T>
    class ReferenceWrapper{
    public:
    	explicit ReferenceWrapper(T& t) :
    		t_(&t){};
    	operator T&() const{
    		return *t_;
    	}
    
    	T& Get() const{
    		return *t_;
    	}
    	T* GetPointer() const{
    		return t_;
    	}
    	void Print(){
    		cout << *t_ << endl;
    	}
    private:
    	T* t_;
    };
    
    template<typename T>
    ReferenceWrapper<T> GetRW(){
    	static T t = 0;
    	return ReferenceWrapper<T>(t++);
    }
    
    int Func(){
    	static int a = 0;
    	return a++;
    }
    int main(){
    	int value = 10;
    	ReferenceWrapper<int> rw(value);	//构造函数
    	cout << rw + 100 << endl;
    	int value1 = 100 + value;
    
    	rw = ReferenceWrapper<int>(value1);	//赋值号,进行构造
    
    	value = rw;	//调用 T& operator() 进行隐式转换,将对象转换为 int类型
    
    	rw.Get() = value;	//返回T&, 可以进行赋值操作
    	*rw.GetPointer() = value;	//返回 T*,然后进行赋值
    	
    	(int&)rw = value;	//将rw隐式转换为 T&,这时候为右值;需要进行(int&)显示转换来进行赋值操作
    
    //	rw = value;		//出错, T& operator() 函数进行隐式转换,只能作为右值,不能作为左值
    
    
    	//函数返回一个自定义类型的变量,为右值
    	//但是对于自定义类型,右值可以调用类的成员函数,即 operator = ,则可以放在=左边
    	GetRW<int>() = ReferenceWrapper<int>(value1);
    	
    	//函数返回一个内嵌类型的变量,该变量为右值。不能放在=左边
    	Func() = 100;
    
    	//右值调用类内部的成员函数
    	GetRW<int>().Print();
    	
    
    	//Func 函数返回一个临时变量,为右值
    	//右值可以调用成员函数,只能被const 类型的引用所指向。
    	const int & tmp1 = Func();
    	int & tmp2 = Func();
    	
    	//左值既可以被const也可以被非const类型的引用所指向
    	int a = Func();
    	const int& tmp3 = a;
    	int& tmp4 = a;
    
    	return 0;
    }
    
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4764511.html
Copyright © 2011-2022 走看看