使用 (copy|move) & swap 方式 没有处理自赋值

无父类示例

class Widget {
public:
    Widget() {
        this->x = new int;
        std::cout << (this) << " ";
        std::cout << "Constructor called" << std::endl;
    }
    Widget(const Widget& rhs) {
        this->x = new int(*(rhs.x));
        std::cout << (this) << " ";
        std::cout << "Copy constructor called" << std::endl;
    }
    Widget(Widget&& rhs) {
        this->x = rhs.x;
        rhs.x = nullptr;
        std::cout << (this) << " ";
        std::cout << "Move constructor called" << std::endl;
    }
    Widget& operator=(const Widget& rhs) {
        Widget(rhs).swap(*this);
        std::cout << (this) << " ";
        std::cout << "Copy assign called" << std::endl;
        return *this;
    }
    Widget& operator=(Widget&& rhs) noexcept {
        Widget(std::move(rhs)).swap(*this);
        std::cout << (this) << " ";
        std::cout << "Move assign called" << std::endl;
        return *this;
    }
    ~Widget() {
        if (this->x != nullptr) delete x;
        this->x = nullptr;
        std::cout << (this) << " ";
        std::cout << "xigou" << std::endl;
    }

    void swap(Widget& rhs) {
        using std::swap;
        // swap(static_cast<Father&>(*this), static_cast<Father&>(rhs)); // 如果有父类,进行父类的swap
        swap(x, rhs.x);
    }
    int* x;
};

有父类示例 自定义Vector类 部分源代码

template <typename T, typename Allocator = std::allocator<T>>
class Vector : Allocator {
public:
    Vector() = default;
    explicit Vector(const Allocator& alloc) : Allocator(alloc) {}
    Vector(size_t n, const T& value = T(),
           const Allocator& alloc = Allocator())
        : Allocator(alloc)
    {
        begin_ = Allocator::allocate(n);
        end_cap_ = begin_ + n;
        try {
            for (end_ = begin_; end_ != end_cap_; ++end_) {
                new (end_) T(value);
            }
        }
        catch (...) {
            destroy(begin_, end_);
            Allocator::deallocate(begin_, n);
            throw;
        }
    }
    Vector(const Vector& rhs) : Allocator(rhs)
    {
        size_t size = rhs.size();
        if (size != 0) {
            begin_ = Allocator::allocate(size);
            try {
                copy(rhs.begin_, rhs.end_, begin_);
            }
            catch (...) {
                Allocator::deallocate(begin_, size);
                throw;
            }
            end_cap_ = end_ = begin_ + size;
        }
    }
    Vector(Vector&& rhs) : Allocator(std::move(rhs))
    {
        begin_ = rhs.begin_;
        end_ = rhs.end_;
        end_cap_ = rhs.end_cap_;
        rhs.begin_ = rhs.end_ = rhs.end_cap_ = nullptr;
    }
    Vector& operator=(const Vector& rhs)
    {
        Vector(rhs).swap(*this);
        return *this;
    }
    Vector& operator=(Vector&& rhs)
    {
        Vector(std::move(rhs)).swap(*this);
        return *this;
    }
    ~Vector()
    {
        if (begin_ != nullptr) {
            destroy(begin_, end_);
            Allocator::deallocate(begin_, end_cap_ - begin_);
        }
    }

    void swap(Vector& rhs)
    {
        using std::swap;
        swap(begin_, rhs.begin_);
        swap(end_, rhs.end_);
        swap(end_cap_, rhs.end_cap_);
        swap(static_cast<Allocator&>(*this), static_cast<Allocator&>(rhs));
    }
private:
    static void copy(T* begin, T* end, T* target)
    {
        T* ptr = target;
        try {
            while (begin != end) {
                new (ptr) T(*begin);
                ++begin;
                ++ptr;
            }
        }
        catch (...) {
            destroy(target, ptr);
            throw;
        }
    }
    static void destroy(T* begin, T* end)
    {
        for (T* ptr = begin; ptr != end; ++ptr) {
            ptr->~T();
        }
    }
    T* begin_{};
    T* end_{};
    T* end_cap_{};
};

月球上的柑橘
1 声望0 粉丝