C++ 构造函数

在C++中构造函数的种类纷繁复杂. 有默认构造函数, 拷贝构造函数, 移动构造函数和重载的构造函数. 还包括以相关联的赋值函数和移动赋值函数. 下面通过实现一个转移所有权的智能指针, 一窥构造函数的用法. 下面是具体的例子:

#include <cassert>
#include <iostream>

// 转移所有权智能指针
template <typename T> class smart_pointer {
  public:
    // 默认构造函数
    smart_pointer() noexcept : m_ptr(new T()) {
        std::cout << "调用默认构造函数" << std::endl;
    }

    smart_pointer(const T &ptr) noexcept : m_ptr(new T(ptr)) {
        std::cout << "调用重载构造函数" << std::endl;
    }

    // 拷贝构造函数
    smart_pointer(smart_pointer &ptr) noexcept {
        std::cout << "调用拷贝构造函数" << std::endl;
        m_ptr = ptr.release();
    }

    // 赋值
    smart_pointer &operator=(smart_pointer &ptr) noexcept {
        std::cout << "调用赋值函数" << std::endl;
        smart_pointer tmp(ptr); // 转移所有权
        swap(tmp);
        return *this;
    }

    // 移动构造函数
    smart_pointer(smart_pointer &&ptr) noexcept {
        std::cout << "调用移动构造函数" << std::endl;
        m_ptr = ptr.release();
    }

    // 移动赋值
    smart_pointer &operator=(smart_pointer &&ptr) noexcept {
        std::cout << "调用移动赋值函数" << std::endl;
        smart_pointer tmp(ptr); // 转移所有权
        swap(tmp);
        return *this;
    }

    void swap(smart_pointer &ptr) noexcept { std::swap(m_ptr, ptr.m_ptr); }

    // 释放所有权
    T *release() noexcept {
        T *tmp = m_ptr;
        m_ptr = nullptr;
        return tmp;
    }

    T *get() const noexcept { return m_ptr; }

    ~smart_pointer() {
        if (m_ptr)
            delete m_ptr;
    }

  private:
    T *m_ptr;
};

template<typename T>
void swap(smart_pointer<T> &lhs, smart_pointer<T> &rhs) noexcept {
    lhs.swap(rhs);
}

int main(void) {
    // 调用重载构造函数
    smart_pointer<std::string> s{"hello world!"};
    std::cout << *s.get() << std::endl;
    std::cout << std::endl;

    // 调用拷贝构造函数
    smart_pointer<std::string> s2(s);
    std::cout << *s2.get() << std::endl;
    assert(s.get() == nullptr);
    std::cout << std::endl;

    // 调用拷贝构造函数
    smart_pointer<std::string> s3 = s2;
    std::cout << *s3.get() << std::endl;
    assert(s2.get() == nullptr);
    std::cout << std::endl;

    // 调用默认构造函数
    // 调用赋值函数
    // 调用拷贝构造函数
    smart_pointer<std::string> s4;
    s4 = s3;
    std::cout << *s4.get() << std::endl;
    assert(s3.get() == nullptr);
    std::cout << std::endl;

    // 调用移动构造函数
    smart_pointer<std::string> s5 = std::move(s4);
    std::cout << *s5.get() << std::endl;
    assert(s4.get() == nullptr);
    std::cout << std::endl;

    // 调用默认构造函数
    // 调用移动赋值函数
    // 调用拷贝构造函数
    smart_pointer<std::string> s6;
    s6 = std::move(s5);
    std::cout << *s6.get() << std::endl;
    assert(s5.get() == nullptr);

    return 0;
}

如果觉得有帮助,可以扫描右边的微信打赏码支持一下.

Leave a Reply

Your email address will not be published. Required fields are marked *