如何有效地移动具有大量POD成员的班级?例:
struct{
int a1;
int a2;
int a3;
...
...
...
};
Run Code Online (Sandbox Code Playgroud)
通过'move',我的意思是行为类似于移动语义(std :: move).
Che*_*Alf 13
POD不移动,只是复制.因为没有间接性.因此,只需使用普通的赋值,并要求编译器针对您的任何效率进行优化.记得在系统地测量之前(地球上你做的不同)以及之后.还要考虑浪费的程序员时间,即金钱,是否值得进行微优化.
Nic*_*las 12
这个问题表明对C++ 11中的运动缺乏了解.
复制具有指针或以其他方式拥有资源的对象时,有两种方法可以使该复制发生.您可以复制指针/资源引用,也可以分配新对象/资源并将原始对象/资源的值复制到新对象/资源中.
在第一种情况下,您将留下两个引用同一对象的对象.Qt做了很多.如果您使用一个对象来修改它引用的内容,那么您也在修改另一个对象.您通常需要某种引用计数器,以便不会双重删除指针或双重释放资源.
在第二种情况下,您将留下两个完全独立的对象.这通常称为"值语义",因为如果将一个POD复制到另一个POD,则之后会有两个完全独立的对象.改变一个不会改变另一个.
移动语义是一种C++ 11机制,允许通常具有值语义的对象在特定条件下具有引用语义.它本质上允许对象窃取另一个对象实例引用的指针/资源.
例如,拿std::vector
; 这只是一个动态分配和调整大小的数组的包装器.与大多数C++标准库对象一样,vector
实现值语义.如果复制a vector
,则新向量必须分配一个新数组,并将旧元素中的每个元素复制到新数组中.完成后,您将拥有两个完全独立的阵列.
移动语义是一种将a中包含的数组转移vector
到另一个中的方法.在操作之后,移动源对象是"空的"(技术上处于未定义状态,但它实际上与它分配的数据分开).新的vector
现在具有与旧的完全相同的指针vector
; new vector
将删除它未分配的内存.
如您所见,这完全基于拥有资源的对象的概念.vector
分配并拥有一个数组; 它的析构函数会破坏它.这就是你如何定义所有权.运动是关于转移所有权.
POD无法表达指针或资源的所有权,因为POD必须具有琐碎的析构函数(即:不执行任何操作的析构函数).因为POD不能表达所有权,所以没有什么可以移动的.如果对象没有任何内容,则无法在对象之间转移所有权.
你必须带来工程判断才能发挥作用.想象一个例子,你在谈论是否使用a std::array<int, N>
或a std::vector<int>
with N
items,其中N
是编译时常量.
什么时候N
非常小,std::array<int, N>
是明显的赢家,因为没有堆分配.副本(以及相当于副本的动作)很便宜.
什么时候N
非常大,std::vector<int>
是明显的胜利者,因为虽然有一个堆分配,并且一个人可以移动vector
,只需要移动3个字的成本,无论大小如何N
.
什么时候N == 3
,毫无疑问哪个是更好的选择.当N == 3,000,000
毫无疑问这是更好的选择.
作为设计师,你的工作就是进入这两个极端之间的灰色区域并做出正确的决定.没有永远正确的决定.针对预期用例的性能测量有很长的路要走.使用<chrono>
那些性能测量.如果您不知道是什么<chrono>
,请搜索stackoverflow.
归档时间: |
|
查看次数: |
2993 次 |
最近记录: |