- 主题:c++真是快被标准委员会玩成花了啊
所以说啊,这个看完不用就会忘记
得在使用中记得使用场景
还得理解左值引用和右值引用
所以我糊涂的就是,为啥不把编译后的中间码列出来
比如 不使用move是这样,使用了move是这样
我觉得最终还是要映射到汇编语句,理解了汇编语句才能搞明白
否则就是记各种使用场景
要么就是楼主说得就是为了几个使用场景,为了效率,打的补丁。
【 在 toutouqi 的大作中提到: 】
: 可不可以这样理解,move就是不保证输入参数数据完整性的拷贝,目的是为了某些情况下减少内存拷贝?
: 用move的场景,如果改用指针,对象指针直接赋值,再把原指针赋0,连普通成员变量的拷贝都省了,看起来似乎比用move概念更清楚。不知道啥场景必须设计成用move而不用指针?
--
修改:littleSram FROM 114.254.9.*
FROM 114.254.9.*
move是对象内部的资源/状态的转移(通常认为资源的复制是高开销操作,内存/文件句柄/socket句柄等都是资源)。
老对象被掏空了,废弃了,所以也有人把这个说成是对象的所有权的转移。可以不纠结字面说法。
用指针的话,编译阶段不好对对象进行跟踪,只能码农自己纯手动进行指针的跟踪,或者无脑用shared_ptr(下策)
【 在 toutouqi 的大作中提到: 】
: 可不可以这样理解,move就是不保证输入参数数据完整性的拷贝,目的是为了某些情况下减少内存拷贝?
: 用move的场景,如果改用指针,对象指针直接赋值,再把原指针赋0,连普通成员变量的拷贝都省了,看起来似乎比用move概念更清楚。不知道啥场景必须设计成用move而不用指针?
--
FROM 125.35.123.*
举一个场景:
有一个结构,我们要parse一些json数据,用parse出来的数据填充这个结构的各个字段,
然后把这个结构插入到表里(map/set/vector里)
struct MyStruct {
m1;
m2;
m3;
};
for(...) {
MyStruct temp;
temp.m1 = ParseJson1();
temp.m2 = ParseJson2();
temp.m3 = ParseJson3();
myTable.emplace_back(std::move(temp));
}
临时变量temp每次循环完都是废弃的,temp里的资源直接move走完事。
当然,也可以用裸指针
for(...) {
auto temp = new MyStruct;
temp->m1 = ParseJson1();
temp->m2 = ParseJson2();
temp->m3 = ParseJson3();
myTable.emplace_back(temp);
}
不过,最后还不能忘了myTable中的每个指针要释放掉。
for(auto &p : myTable) {
delete p;
}
还可以用std::unique_ptr,不过最后也是要执行move:
for(...) {
auto temp = std::make_unique<MyStruct>();
temp->m1 = ParseJson1();
temp->m2 = ParseJson2();
temp->m3 = ParseJson3();
myTable.emplace_back(std::move(temp));
}
我倾向于第一种写法。
【 在 toutouqi 的大作中提到: 】
: 可不可以这样理解,move就是不保证输入参数数据完整性的拷贝,目的是为了某些情况下减少内存拷贝?
: 用move的场景,如果改用指针,对象指针直接赋值,再把原指针赋0,连普通成员变量的拷贝都省了,看起来似乎比用move概念更清楚。不知道啥场景必须设计成用move而不用指针?
--
FROM 125.35.123.*
和rust相比,c++的move就是个半成品,连基本的move后原对象失效检查都做不到。
move的使用复杂度和内存管理是一个级别的。在项目中大规模使用move将是灾难。
【 在 DoorWay 的大作中提到: 】
: 好吧。我不该谈哲学,不该引用"old dog cannot learn new trick"这句话。但我保证不是废话,但我不能保证你最终能弄明白。
:
: 你现在到底是遇到了move的什么问题?
: ...................
--来自微微水木3.5.12
--
FROM 223.167.168.*
总有个别人的,但是
【 在 allegro 的大作中提到: 】
: 每个人都觉得语言有90%没用,可惜所有人不是同一个90%
--
FROM 153.0.153.*
所以c++所谓的你不知道的规则不会harm你就是扯淡的
【 在 god4 的大作中提到: 】
: 总有个别人的,但是
:
--
FROM 213.95.148.*
一我觉得本质是null的表示问题,要表示空,需要一个非空。不评价。
二move在代码库里,一是享受stl里的自然的好处,如swap,二是unique pointer。如果内写一个类型,都煞有介事的实现move copy move assign,不是练手,就是专业的库作者。不是普通情况吧。
【 在 KillnCov 的大作中提到: 】
: 和rust相比,c++的move就是个半成品,连基本的move后原对象失效检查都做不到。
: move的使用复杂度和内存管理是一个级别的。在项目中大规模使用move将是灾难。
--
FROM 124.114.151.*
还有就是,普通的结构体,不实现copy operation 、move operation 、destructor,编译器会生成move版本的操作,放到容器里也能享受一些好处。
总之move除了专业库作者,不会大规模用的。除了unique_ptr future之类,就是享受编译器自己上阵的优化。
【 在 DoorWay 的大作中提到: 】
: 一我觉得本质是null的表示问题,要表示空,需要一个非空。不评价。
: 二move在代码库里,一是享受stl里的自然的好处,如swap,二是unique pointer。如果内写一个类型,都煞有介事的实现move copy move assign,不是练手,就是专业的库作者。不是普通情况吧。
--
FROM 124.114.151.*
我习惯第二种,虽然指针有需要删除的麻烦。第一种,move会让编译器直接把临时变量的地址存到容器(比如vector)里,还是也得造个对象然后调用move拷贝函数进行成员变量的拷贝?另外,第一种如果对容器vector初始化(比如10个元素),相当于得调用10遍元素类的构造函数,而指针就没有这个问题。
【 在 z16166 的大作中提到: 】
: 举一个场景:
: 有一个结构,我们要parse一些json数据,用parse出来的数据填充这个结构的各个字段,
: 然后把这个结构插入到表里(map/set/vector里)
: ...................
--
FROM 223.104.38.*
第二种是裸指针,全手动管理内存,也容易搞出异常时不安全的代码,应该一般是不推荐的。
第一种是不会存临时变量地址到表里的,不然那个写法就是错误的,不能用。
【 在 toutouqi 的大作中提到: 】
: 我习惯第二种,虽然指针有需要删除的麻烦。第一种,move会让编译器直接把临时变量的地址存到容器(比如vector)里,还是也得造个对象然后调用move拷贝函数进行成员变量的拷贝?另外,第一种如果对容器vector初始化(比如10个元素),相当于得调用10遍元素类的构造函数,而指针就没有这个问题。
--
修改:z16166 FROM 125.35.123.*
FROM 125.35.123.*