左、右值(C++基础)

左、右值

左值:有地址的值

右值:字面量的值,无地址(临时对象)

static int i = 10;
int& getValue() {
	return i;
}
    getValue() = 5;
	i = 7;
	std::cout << i << std::endl;

返回参数带&的方法可接收右值。

void PrintName(std::string&& name) {
	std::cout << "r" << name << std::endl;
}
void PrintName(const std::string& name) {
	std::cout << "l" << name << std::endl;
}
 	std::string firstName = "lhx";
	std::string lastName = "zxl";
	std::string allName = firstName + lastName;
	PrintName(firstName + lastName);
	PrintName(allName);

&&是接收右值的意思,且在&之前加const也可以使传参接收右值,但是如果重载方法中同样含有&&的话会优先&&。

移动语义

右值是c++11添加的,移动语义必须要右值,移动语义用于将某些对象指针无复制的移动到其他对象指针上来完成对象内容的转换,换句话来说就是浅拷贝

class String {
public:
	String() = default;
	String(const char* temp) {
		printf("Created!\n");
		m_Size = strlen(temp);
		m_Data = new char[m_Size];
		memcpy(m_Data,temp,m_Size);
    }
	void Print() {
		for (uint32_t i = 0; i < m_Size; i++)
			printf("%c",m_Data[i]);
		printf("\n");
	}
	String(const String& temp) {
		printf("Copied!\n");
		m_Size = temp.m_Size;
		m_Data = new char[m_Size];
		memcpy(m_Data, temp.m_Data, m_Size);
	}
	~String() {
		printf("destroyed !\n");
		delete m_Data;
	}
private:
	char* m_Data;
	uint32_t m_Size;
};
class Entity {
public:
	Entity(const String& name) : m_Name(name) {}
	void PrintName() {
		m_Name.Print();
	}
private:
	String m_Name;
};
int main() {
	Entity entity(String("lhx"));
	entity.PrintName();
}

在上述代码中进行了依次copied,发生在构造函数时,将String类型的“lhx”构造复制给String对象。我们现在想通过移动语义来解决这个问题,通过增加右值接收构造函数来对指向“lhx“的指针进行更换,没有进行深拷贝!!!

	String(String&& other) noexcept {
		printf("Moved!\n");
		m_Size = other.m_Size;
		m_Data = other.m_Data;
		other.m_Size = 0;
		other.m_Data = nullptr;
	}
	String& operator=(String&& temp ) {
		printf("Moved!\n");
		if (this != &temp) {
			delete[] m_Data;
			m_Data = temp.m_Data;
			m_Size = temp.m_Size;
			temp.m_Data = nullptr;
			temp.m_Size = 0;
		}
		return *this;
	}//添加在string类中
int main() {
	//Entity entity(String("lhx"));
	//entity.PrintName();

	String string = "hello!";
	String dest = std::move(string);

	String string = "hello";
	String dest = std::move(string);
	//将对象转为临时对象
	string.Print();
	dest.Print();

	dest = std::move(string);
	dest.operator=(std::move(string));

	string.Print();
	dest.Print();
	std::cin.get();
};

刚才进行的是对右值的移动语义。现在进行对两个有值的对象的移动语义,会使用到std::move函数,它的作用是将一个左值对象转变为一个右值从而避免复制。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想进大厂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值