• 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;
    }
    
  • 相关阅读:
    jquery选择器中逗号的使用
    超大文件上传和断点续传的代码
    超大文件上传和断点续传的源代码
    超大文件上传和断点续传的源码
    超大文件上传和断点续传的控件
    超大文件上传和断点续传的插件
    杨辉三角
    pkg-config的用法
    c++类的实例化,有没有new的区别
    正则表达式中元字符
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4764511.html
Copyright © 2020-2023  润新知