如何将unique_ptr的移动构造函数和运算符实现为类的私有成员

YlmzCmlttn

我正在尝试编写Matrix类。我正在使用unique_ptr作为存储指针数组。但是,这个unique_ptr是类的私有成员。我想将move构造函数添加到Matrix类中。但是我需要私有的unique_ptr的getter函数,但是当我将unique_ptr作为const变量返回时,我不能使用std :: move,但是当我在没有const引用编译器的情况下返回getter函数时,则不允许这样做。

矩阵

template <typename _T>
    class Matrix_
    {
    private:
        size_t rows_;
        size_t cols_;
        size_t size_;
        std::unique_ptr<_T[]> data_;        
    public:
        Matrix_();
        Matrix_(const Matrix_& _m); //Copy constructor
        Matrix_(Matrix_&& _m) noexcept; //Move constructor
        Matrix_(const size_t& rows);
        Matrix_(const size_t& rows,const size_t& cols);
        Matrix_(const size_t& rows,const size_t& cols,const _T& val);
        //Operators        
        Matrix_& operator=(const Matrix_& _m); //Copy assignment
        Matrix_& operator=(Matrix_&& _m) noexcept; //Move assignment
        //
        //Methods
        size_t getRows()const;
        size_t getCols()const;
        size_t getSize()const;
        const std::unique_ptr<_T[]>& getData()const;
        void copyData(const std::unique_ptr<_T[]>& _data);

        void fill(const _T& val);
        //
        ~Matrix_();
    };
    template <typename _T>
    Matrix_<_T>::Matrix_():rows_(1),cols_(1),size_(rows_*cols_),data_(std::make_unique<_T[]>(size_))
    {
    }
    template <typename _T>
    Matrix_<_T>::Matrix_(const Matrix_& _m):rows_(_m.getRows()),cols_(_m.getCols()),size_(rows_*cols_),data_(std::make_unique<_T[]>(size_))
    {
    }
    template <typename _T>
    Matrix_<_T>::Matrix_(Matrix_&& _m)noexcept:rows_(_m.getRows()),cols_(_m.getCols()),size_(rows_*cols_),data_(std::move(_m.getData()))
    {
    }
    template <typename _T>
    Matrix_<_T>::Matrix_(const size_t& rows):rows_(rows),cols_(1),size_(rows_*cols_),data_(std::make_unique<_T[]>(size_))
    {
    }
    template <typename _T>
    Matrix_<_T>::Matrix_(const size_t& rows,const size_t& cols):rows_(rows),cols_(cols),size_(rows_*cols_),data_(std::make_unique<_T[]>(size_))
    {
    }
    template <typename _T>
    Matrix_<_T>::Matrix_(const size_t& rows,const size_t& cols,const _T& val):rows_(rows),cols_(cols),size_(rows_*cols_),data_(std::make_unique<_T[]>(size_))
    {
        fill(val);
    }
    //Operators
    template <typename _T>
    Matrix_<_T>& Matrix_<_T>::operator=(const Matrix_& _m)
    {   
        rows_ = _m.rows_;
        cols_ = _m.cols_;
        size_ = rows_*cols_;
        data_ = std::make_unique<_T[]>(size_);
        copyData(_m.getData());
        return *this;
    }
    template <typename _T>
    Matrix_<_T>& Matrix_<_T>::operator=(Matrix_&& _m)noexcept{
        rows_ = _m.rows_;
        cols_ = _m.cols_;
        size_ = rows_*cols_;
        data_ = std::move(_m.getData());
        return *this;
    }
    //
    //Methods
    template <typename _T>size_t Matrix_<_T>::getRows()const{return rows_;}
    template <typename _T>size_t Matrix_<_T>::getCols()const{return cols_;}
    template <typename _T>size_t Matrix_<_T>::getSize()const{return size_;}    
    template <typename _T>const std::unique_ptr<_T[]>& Matrix_<_T>::getData()const{return data_;}
    template <typename _T>void Matrix_<_T>::copyData(const std::unique_ptr<_T[]>& _data){        
        for(uint i=0;i<size_;i++){data_[i]=_data[i];}
    }
    template <typename _T>void Matrix_<_T>::fill(const _T& val){
        for(uint i=0;i<size_;i++){data_[i]=val;}
    }
    //
    template <typename _T>
    Matrix_<_T>::~Matrix_()
    {
    }

测试文件

int main()
{
   Matrix_<double> a(10,10,5.0);
   Matrix_<double> b(10,10);
   b = std::move(a);
   std::cout<<b.getData()[0]<<std::endl;

   return 0;
}

错误

error: use of deleted function ‘std::unique_ptr<_Tp [], _Dp>& std::unique_ptr<_Tp [], _Dp>::operator=(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = double; _Dp = std::default_delete<double []>]’
         data_ = std::move(_m.getData());
         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/locale_conv.h:41:0,
                 from /usr/include/c++/7/locale:43,
                 from /usr/include/c++/7/iomanip:43,
                 from /home/cemo/YZlib/Examples/Test.cpp:3:
/usr/include/c++/7/bits/unique_ptr.h:654:19: note: declared here
       unique_ptr& operator=(const unique_ptr&) = delete;
Aschepler

不要在移动构造函数或移动分配中使用吸气剂。只需直接使用该成员。我可能会对所有成员都这样做,以使他们很明显地相互匹配。

template <typename T>
Matrix<T>::Matrix(Matrix &&m) noexcept :
    rows_(m.rows_), cols_(m.cols_), size_(m.size_), data_(std::move(m.data_))
{
   // changes needed to m?
}

template <typename T>
Matrix<T>& Matrix<T>::operator=(Matrix &&m) noexcept
{
    rows_ = m.rows_;
    cols_ = m.cols_;
    size_ = m.size_;
    data_ = std::move(m.data_);
    // changes needed to m?
    return *this;
}

类始终有权访问其自己的成员(无论通过哪个对象访问它们)。

m由于它data_是一个空指针,因此请务必考虑现在该怎么办它的rows_cols_size_应该设置为零,还是不重要?通常,无论您决定对班级意味着什么,移出的对象都应保持“有效但未指定”状态。至少,调用析构函数应该是有效的,并将其分配给其他对象应该可以正常工作;这已经是事实了。

由于这里不需要使用getter,因此,这是一个单独的问题,即公共接口是否应该完全包含getter,或者是否应该具有更便捷的return类型(如justconst T*或)T*

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何迭代(在类外部)作为矢量<unique_ptr <T >>的私有成员

使用unique_ptr <>实现移动构造函数和赋值

如何为类 unique_ptr 创建运算符->

F#类将接口实现为私有成员,为什么呢?

错误C2248:'std :: unique_ptr <_Ty> :: unique_ptr':无法访问在类'std :: unique_ptr <_Ty>'中声明的私有成员

定义移动分配运算符时,如何将包含unique_ptr的对象分配给其类型的矢量?

移动构造函数和移动赋值运算符在不将指针作为成员变量保存且不管理资源的类中有意义吗?

使用运算符()从代理类返回unique_ptr成员变量

C ++ 20中的运算符==和<=>应该实现为成员还是自由函数?

如何在临时容器类中实现复制构造函数和赋值运算符?

我应该如何为矩阵类实现复制构造函数和赋值运算符?

用户定义类型的重载运算符=具有unique_ptr数据成员

将具有unique_ptr的类的构造函数作为成员复制到抽象类

<没有成员的类的运算符

如何在类构造函数中创建新值并分配给私有unique_ptr?

从私有成员变量的成员方法返回unique_ptr

如何将+和+ =运算符重载为非成员函数?

在公共成员函数中返回私有unique_ptr

如何允许 std::unique_ptr 访问类的私有析构函数或使用私有析构函数实现 C++ 工厂类?

如何从子类的构造函数初始化父类的私有成员

在带有 std::unique_ptr 的类赋值运算符中,

移动构造函数并移动类的赋值运算符

如何在unique_ptr上调用函数调用运算符?

移动构造函数和移动分配。基类的运算符

即使我实现了副本分配运算符,类还是可以移动构造和分配的

移动unique_ptr的构造函数和向量

在具有智能指针的类上正确实现Copy构造函数和Equals运算符

重载了数据成员,构造函数和运算符的抽象基类

抽象类可以在C ++ 11中具有构造函数和私有成员吗