关于右值引用的问题

qq_32966993 2016-08-30 05:52:30
class RValueTest
{
public:
RValueTest(int&& r_value)
{
cout << "RValue Constructor" << r_value << endl;
}

RValueTest(int& l_value)
{
cout << "LValue Constructor" << endl;
}
};


class RValueTest1
{
public:
RValueTest1(int&& r_value)
{
int&& jjj = std::move(r_value);
RValueTest a1(jjj);
}

RValueTest1(int& l_value)
{
cout << "LValue Constructor" << endl;
}
};


int main()
{
RValueTest1 a1(5);
}

最近在学习右值引用
为啥调用的RValueTest(int& l_value) 左值构造函数
...全文
431 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-08-31
  • 打赏
  • 举报
回复
有名的右值引用是个左值引用 int&& jjj = std::move(r_value); 等同于 int& jjj = std::move(r_value); 效果完全一致。 只有右值引用参数,能某种程度上起到右值引用的效果(并不保证) 右值引用效果,只对临时变量(编译器生成的)起作用。 有时候要显式用 std::move 才会当成右值引用 你这里用 std::move的结果, 初始化有名右值引用, 结果还是得到一个左值引用。
pengzhixi 2016-08-31
  • 打赏
  • 举报
回复
int&& jjj = std::move(r_value); 这里std::move(r_value)的结果是一个xvalue,然后这个xvalue被int&&jjj引用了。 那么标准做了如下规定 In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues 也就是说jjj被当成lvalue了。这样在调用构造函数的时候就是int&而非int&& 如果你想达到目的那么int&& jjj = std::move(r_value); RValueTest a1(jjj);合并成RValueTest a1(move(r_value));
feixiangmenghuan 2016-08-31
  • 打赏
  • 举报
回复
MyString::MyString(MyString&& str)
{
  cout << "右值应用在构造函数的使用-----: " << str.m_data <<endl;
  m_data = str.m_data;
  m_len = str.m_len;
  str.m_data = NULL;
  str.m_len = 0;
}

MyString& MyString::operator=(MyString&& str)
{
	cout << "右值引用在赋值函数中的使用-----: " << str.m_data << endl;
	if (this != &str)
	{
		m_data = str.m_data;
		m_len = str.m_len;
		str.m_data = NULL;
		str.m_len = 0;
	}
	return *this;
}
pengzhixi 2016-08-31
  • 打赏
  • 举报
回复
至于右值引用的作用主要是 一:带来move语义。二:完美转发。 move语义可以让你放心的“偷资源” 提高效率 完美转发 这个涉及到引用折叠。当然你有兴趣可以去搜下这个引用折叠。
pengzhixi 2016-08-31
  • 打赏
  • 举报
回复
给你一个不那么严格的区分 如果能用&(取地址符)来操作的就应该是lvalue,不能的话可以归纳到rvalue,当然标准还弄了个xvalue。这个你就不用管了。
qq_32966993 2016-08-31
  • 打赏
  • 举报
回复
也就是说 右值引用其实只是为了让程序员来区分场合来使用的,增加了一个概念,更方便于程序员来区分左值和右值的场合。 有没有实际用例表明, 在某种情况下用右值比左值更优秀,大致的概念我已经明白了。 谢谢大家的代码,我也测试过了。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
呃,上面那个代码clearStack();的调用应该注释的,居然忘记了。
引用 6 楼 qq_32966993 的回复:
那我在什么场合适合右值引用呢? 既然左值引用已经算是地址级别了,右值引用还能优化多少?
c++11编译器默认支持并实现右值(转移构造函数),所以你不用在意它,代码可以写的很随意。 只要你确认代码调用的是转移构造函数就行。 简单点的判断,就是我之前说的那个,函数返回的是当前内部栈中的申请的对象。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
这份代码你看看吧,我已经写的够详细的了。

void clearStack() {
	char ch[100] = { 0 };
}

class OBJ {
public:
	int i;
	OBJ() { printf("create construction\n"); }
	/*此处的copy和move构造函数,
	只为直观观看调用,并没有实现,
	通过这两个函数生成的对象会造成成员数据i丢失,
	所以下面那两个i!=10
	如此处不显示声明构造函数,编译器会帮你自动生成并实现。
	*/
	OBJ(const OBJ& other) { printf("copy construction\n"); }
	OBJ(OBJ&& other) { printf("move construction\n"); }
};

OBJ testMv() {
	OBJ o;
	o.i = 10;
	printf("testMv::o=%p, o.i=%d\n",&o,o.i);
	return o;
}

OBJ& testMv1() {
	OBJ o;
	o.i = 10;
	printf("testMv1::o=%p, o.i=%d\n", &o, o.i);
	return o;
}

class OBJ1 {
public:
	OBJ o;
	OBJ testMv() {
		o.i = 10;
		printf("testMv::o=%p, o.i=%d\n", &o, o.i);
		return o;
	}
	OBJ& testMv1() {
		o.i = 10;
		printf("testMv1::o=%p, o.i=%d\n", &o, o.i);
		return o;
	}
};

int main()
{
	OBJ1 obj1;
	printf("~~~~~~~~~~~~~~~~construction OBJ1 over~~~~~~~~~~~~~~~~~~~~~~~\n\n");

	printf("~~~~~~~~~~~~~~~~start func~~~~~~~~~~~~~~~~~~~~~~~\n");
	OBJ obj = testMv();
	printf("main::obj=%p,obj.i=%d\n", &obj,obj.i);
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	OBJ& objRef = testMv1();
	/*objRef的实际对象栈已经销毁,之所以objRef.i依旧会是10,
	建议学习一点汇编的基本概念,然后使用VS的反汇编,一目了然。
	简单来说,就是上次调用的栈上的数据还在那里没人管,造成的数据遗留
	clearStack()取消注释并运行
	objRef.i = 0;
	*/
	clearStack();
	printf("main::objRef=%p,objRef.i=%d\n", &objRef, objRef.i);
	printf("\n\n\n");


	printf("~~~~~~~~~~~~~~~~start obj::func~~~~~~~~~~~~~~~~~~~~~~~\n");
	OBJ objMember = obj1.testMv();
	printf("main::objMember=%p,objMember.i=%d\n", &objMember, objMember.i);
	printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	OBJ& objMemberRef = obj1.testMv1();
	printf("main::objMemberRef=%p,objMemberRef.i=%d\n", &objMemberRef, objMemberRef.i);

    return 0;
}
xskxzr 2016-08-30
  • 打赏
  • 举报
回复
引用 6 楼 qq_32966993 的回复:
那我在什么场合适合右值引用呢? 既然左值引用已经算是地址级别了,右值引用还能优化多少?
右值引用本身不具有优化效果,它的作用是让你能通过区分左值和右值编写不同的代码来进行优化。 一个典型的应用就是移动构造函数(通过右值引用来识别右值参数,然后就可以放心大胆地转移(而非拷贝)资源了)。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 5 楼 mymixing 的回复:
概念上一切函数返回的非引用都是右值。 包括构造函数。 丫的,这地方是个坑,项目里的编译器老旧,不支持c++11,代码写着很恶心
呃,这句话越想越不对,越不严谨。 应该说,函数如果返回自身栈中的对象,那么这个对象会被当作右值。 一会上下写的测试代码
qq_32966993 2016-08-30
  • 打赏
  • 举报
回复
那我在什么场合适合右值引用呢? 既然左值引用已经算是地址级别了,右值引用还能优化多少?
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
概念上一切函数返回的非引用都是右值。 包括构造函数。 丫的,这地方是个坑,项目里的编译器老旧,不支持c++11,代码写着很恶心
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
右值引用和引用的实际作用没有区别,他们都是实际对象的别名而已。 你引用怎么用的,右值引用就是怎么用,实际用法其实完全一致。 右值左值仅是一个编译器中的概念。 c++新出的标准,都是为了简化事物的操作和理解,不是为了让实物越来越复杂。

#include <iostream>
using namespace std;

class RValueTest
{
public:
RValueTest(int&& r_value)
{
cout << "r_value:" << r_value << endl;
r_value = 1;
}

RValueTest(int& l_value)
{
cout << "l_value:" << l_value << endl;
l_value = 2;
}
};

int main()
{
int a = 0;
RValueTest a1(std::move(a));
cout << "main_a :"<< a << endl;

RValueTest a2(a);
cout << "main_a :"<< a << endl;
}
qq_32966993 2016-08-30
  • 打赏
  • 举报
回复
那我想问下 这个jjj如果是个右值该如何使用???
fefe82 2016-08-30
  • 打赏
  • 举报
回复
int&& jjj = std::move(r_value); RValueTest a1(jjj); jjj 是一个右值引用,但 ai(jjj) 中的 jjj 是一个左值。 右值引用只是说它可以绑定到一个右值。但当绑定结束,它有了名字之后,使用这个名字将得到一个左值。
qq_32966993 2016-08-30
  • 打赏
  • 举报
回复
调用顺序是 调用了 RValueTest1(int&& r_value) 然后 RValueTest(int& l_value)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧