我在2013年2月发行了#34; Overload"杂志。我理解所提供的代码,但完全我确实错过了它的目的,既不是与std :: auto_ptr的类比,也不是为了节省alloc / dealloc周期。如果有人可以重新解释这个"食谱"用他自己的话说。描述如下:
食谱#2 - 具有'移动'语义的容器食谱#2无疑是一个 相当奇怪的,但每个好的食谱应至少包含一个 奇怪的食谱,所以这里。在高性能代码中,有 场景,您需要有一个存储复杂的容器 对象(包括分配的存储等对象),但那些 对象仅在四处移动,永远不会被复制。提供副本 这些对象的构造函数可能很难(例如,如果 这样的对象包括文件句柄)或对性能不利 原因(如果这样的对象包含已分配的内存,则复制哪个 会很贵)。解决这个问题的一种常见方法是使用一些 一种引用计数指针(或类似的东西) 的auto_ptr<&GT);这是一个可行的选择,但它有相关的成本 额外的分配/解除分配,以及真正的高性能 代码,这可能是一个问题。在这种情况下,一种类似的方法 以下内容可能有所帮助(改写一句谚语,你可以这么说 奇怪的时候需要奇怪的措施) - 见清单2。
//class X is our complicated class
class StackOfX {
// stack is just one example; any other type of
// container (including maps, sets, lists, etc.)
// can be written in a similar manner
struct ShadowX { char data[ sizeof(X) ]; };
typedef vector<ShadowX> ShadowV;
ShadowV v;
void push( /* move-in */ X& x ) {
ShadowX& sx = (ShadowX&)x;
v.insert( v.end(), sx );
}
const X& operator[]( int i ) const {
return (const X&)v[ i ];
}
void pop( /* move-out */ X& x ) {
ShadowV::iterator it = v.end() - 1;
ShadowX& sx = (ShadowX&)x;
sx = *it;
v.erase( it );
}
~StackOfX() {
for( ShadowV::iterator it = v.begin();
it != v.end(); ++it ) {
X& x = (X&)(*it);
x.X::~X();
}
}
};
答案 0 :(得分:1)
代码的要点似乎是能够复制不支持复制的对象,将它们视为字节序列。
这样做并不是一个好主意,但如果要做到这一点,使用memcpy
比使用愚蠢的重新解释更为明确。
C ++ 11引入了对移动语义的支持。在那之前,对于C ++ 03,有Andrei的Mojo东西(然而它从未起飞)。使用移动语义支持对象可以放入容器中,即使它们不可复制。
答案 1 :(得分:0)
C ++ 11完全过时了,C ++ 11直接在语言中提供移动语义的语法。
获取一本实际上很好且最新的书,The Definitive C++ Book Guide and List
引用该页面: 有很多非常糟糕的C ++书籍