来自“Overload”杂志的Strange Recipes

时间:2014-06-28 20:12:53

标签: c++ design-patterns move

我在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();
        }
    }

};

2 个答案:

答案 0 :(得分:1)

代码的要点似乎是能够复制不支持复制的对象,将它们视为字节序列。

这样做并不是一个好主意,但如果要做到这一点,使用memcpy比使用愚蠢的重新解释更为明确。

C ++ 11引入了对移动语义的支持。在那之前,对于C ++ 03,有Andrei的Mojo东西(然而它从未起飞)。使用移动语义支持对象可以放入容器中,即使它们不可复制。

答案 1 :(得分:0)

C ++ 11完全过时了,C ++ 11直接在语言中提供移动语义的语法。

获取一本实际上很好且最新的书,The Definitive C++ Book Guide and List

引用该页面: 有很多非常糟糕的C ++书籍