mardi 30 mai 2017

Compare the habits between move and smart pointer in C++?

In C++11/14, an object can be transfered by move or smark pointer.

(1) This is an example for move:

class MoveClass {
private:
    int *tab_;
    int alloc_;
    void Reset() {
        tab_ = nullptr;
        alloc_ = 0;
    }
    void Release() {
        if (tab_) delete[] tab_;
        tab_ = nullptr;
        alloc_ = 0;
    }

public:
    MoveClass() : tab_(nullptr), alloc_(0) {}
    ~MoveClass() {
        Release();
    }
    MoveClass(MoveClass && other) : tab_( other.tab_ ), alloc_( other.alloc_ ) {
        other.Reset();
    }
    MoveClass & operator=(MoveClass && other) {
        if (this == &other) return *this;
        std::swap(tab_, other.tab_);
        std::swap(alloc_, other.alloc_);
        return *this;
    }
    void DoSomething() { /*...*/ }
};

When we use this movable MoveClass, we can write code like this :

int main() {
    MoveClass a;
    a.DoSomething();  // now a has some memory resource
    MoveClass b = std::move(a);  // move a to b
    return 0;
}

Always write move-constructor/move-operator= is boring, use shared_ptr/unique_ptr some times have the same effect, just like java, reference/pointer everywhere.

(2) Here is the example:

class NoMoveClass {
private:
    int *tab_;
    int alloc_;
    void Release() {
        if (tab_) delete[] tab_;
        tab_ = nullptr;
        alloc_ = 0;
    }

public:
    NoMoveClass() : tab_(nullptr), alloc_(0) {}
    ~NoMoveClass() {
        Release();
    }
    MoveClass(MoveClass && other) = delete;
    MoveClass & operator=(MoveClass && other) = delete;
    void DoSomething() { /*...*/ }
};

We can use it like this:

int main() {
    std::shared_ptr<NoMoveClass> a(new NoMoveClass());
    a->DoSomething();
    std::shared_ptr<NoMoveClass> b = a; // also move a to b by copy pointer.
    return 0;
}

Is it a good habit to always use the 2nd one?

Why many libraries, STL use the 1st one, not the 1st one ?

Aucun commentaire:

Enregistrer un commentaire