How to implemet copy constructor in C++

this is the header of a class that I have been designing for an assignment. I have included constructors, a destructors, as well as overloaded operators. Could you give me a hint how to properly define the constructors in a class using c++ 20 most recent features in an efficient way.

#ifndef VECTOR_DOUBLE_H
#define VECTOR_DOUBLE_H


#include <memory>
#include <vector>

class vector_double {
public:
    vector_double(int size);
    vector_double(std::initializer_list<double> lst);
    vector_double(const double* array, int size);

    vector_double(const vector_doubler& other);
    vector_doubleoperator=(const vector_double& other);

    // because I use a managed pointer I don't need a destructor
    ~vector_double() noexcept = default;

    void set(int index, double val);
    double& get(int index);
    const double& get(int index) const;

    int size() const;
    void reset(double val);

    void fill_from(std::initializer_list<double> lst);
    void fill_from(const double* array, int size);

    int copy_to(std::vector<double>& vec) const;

    double& operator[](int index);
    const double& operator[](int index) const;

    operator double() const;

    vector_double add(const vector_double& other) const;
    vector_doubleadd(double number) const;
    vector_doublemul_by(double number) const;

    void resize(int size);
    friend std::ostream& operator<<(std::ostream& out, const vector_double& vec);
private:
    std::unique_ptr<double[]> m_array;
    int m_size;
};

inline std::ostream& operator<<(std::ostream& out, const vector_double& vec){
    if (vec.m_size == 0){
        out << "{ }";
    }
    else{
        auto first = true;
        out << '{';
        for (int i=0; i < vec.m_size; ++i){
            if (!first)
                out << ", ";
            else
                first = !first;

            out << vec.m_array[i];
        }
        out << '}';
    }
    return out;
}

#endif //VECTOR_DOUBLE_H

Answer

This Example definition may help, I tried sticking to the C++ 20 features:


    #include <cmath>
    #include "vector_double.h"
    
    vector_double::vector_double(int size):
        m_array{ new double[size] },
        m_size{size}
    {}
    
    vector_double::vector_double(std::initializer_list<double> lst):    //Constructor that takes an init list
        vector_double(lst.size())                       
        {
            std::copy(lst.begin(), lst.end(), m_array.get());
        }
    
    vector_double::vector_double(const double* array, int size):    //Constructor that takes array and size 
        vector_double(size)
        {
    //    std::copy(array, array + size, m_array.get());
            std::copy(&array[0], &array[size], m_array.get());
        }
    
    vector_double::vector_double(const vector_double& other):    //Copy Constructor     
        vector_double(other.m_size)
    {
        std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
    }
    
    vector_double& vector_double::operator=(const vector_double& other) {
    if (this != &other) {
        if (m_size != other.m_size) {
            auto* array = new double[other.m_size];
            m_array.reset(array);
            m_size = other.m_size;
        }

        std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
    }
    return *this;
}
    
    void vector_double::set(int index, double val) {
        if (index < 0 || index > m_size)
            throw std::out_of_range("oooh my!");
        m_array[index] = val;
    }
    
    double& vector_double::get(int index) {
        if (index < 0 || index > m_size)
            throw std::out_of_range("oooh my!");
        return m_array[index];
    }
    
    const double& vector_double::get(int index) const {
        if (index < 0 || index > m_size)
            throw std::out_of_range("oooh my!");
        return m_array[index];
    }
    
    int vector_double::size() const {
        return m_size;
    }
    
    void vector_double::reset(double val) {
       for (int i=0; i<m_size; ++i){
           m_array[i] = val;
       }
    }
    
    void vector_double::fill_from(std::initializer_list<double> lst) {
        int size = std::min((int)lst.size(), m_size);
    
        std::copy(lst.begin(), lst.begin() + size, &m_array[0]);
    
    }
    
    void vector_double::fill_from(const double* array, int size) {
        size = std::min(size, m_size);
    
        for (int i = 0; i < size; ++i) {
            m_array[i] = array[i];
        }
    }
    
    int vector_double::copy_to(std::vector<double>& vec) const {
        for (int i = 0; i < m_size; ++i) {
            vec.push_back(m_array[i]);
        }
        return m_size;
    }
    
    double& vector_double::operator[](int index) {
        return m_array[index];
    }
    
    const double& vector_double::operator[](int index) const {   //Overloading "[]" operator
        return m_array[index];
    }
    
    vector_double::operator double() const {
        double sum = 0.0;
        for (int i = 0; i < m_size; ++i) {
            sum += m_array[i] * m_array[i];
        }
        return std::sqrt(sum);
    }
    
    vector_double vector_double::add(const vector_double& other) const {
        if (m_size != other.m_size)
            throw std::logic_error("size mismatch");
    
        auto copy = *this;
        for (int i = 0; i < m_size; ++i) {
            copy[i] += other[i];
        }
        return copy;
    }
    
    vector_double vector_double::add(double number) const {
        auto copy = *this;
        for (int i = 0; i < m_size; ++i) {
            copy[i] += number;
        }
        return copy;
    }
    
    vector_double vector_double::mul_by(double number) const {
        auto copy = *this;
        for (int i = 0; i < m_size; ++i) {
            copy[i] *= number;
        }
        return copy;
    }
    
    void vector_double::resize(int size) {
    if (size != m_size){

        auto array = new double[size] {0,};

        auto common = std::min(size,m_size);

        for (int i = 0; i < common; ++i) {
            array[i] = m_array[i];
        }

        m_array.reset(array);
        m_size = size;

    }
}