简体   繁体   English

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

[英]How I can implement move constructor and operator for unique_ptr as a private member of class

I am trying to write Matrix class.我正在尝试编写Matrix类。 I am using unique_ptr as a storage pointer array.我使用unique_ptr作为存储指针数组。 But this unique_ptr is private member of class.但是这个 unique_ptr 是类的私有成员。 I want to add move constructor to my Matrix class.我想向我的 Matrix 类添加移动构造函数。 But I need getter function for private unique_ptr but when I return unique_ptr as a const variable I can not use std::move but when I return getter function without const reference compiler doesn't not allow this.但是我需要私有unique_ptr 的getter函数,但是当我将 unique_ptr 作为 const 变量返回时,我不能使用 std::move 但是当我返回没有 const 引用的 getter 函数时,编译器不允许这样做。

Matrix.hpp矩阵.hpp

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_()
    {
    }

Test.cpp测试文件

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错误

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;

Don't use the getter in your move constructor or move assignment.不要在移动构造函数或移动赋值中使用 getter。 Just use the member directly.直接使用会员即可。 I would probably do this for all members, to make it obvious they match up.我可能会为所有成员执行此操作,以使其明显匹配。

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;
}

A class always has access to its own members (no matter which object they're accessed through).一个类总是可以访问它自己的成员(无论它们是通过哪个对象访问的)。

Be sure to consider what should happen to m now that its data_ is a null pointer.一定要考虑现在m会发生什么,因为它的data_是一个空指针。 Should its rows_ , cols_ , and size_ be set to zero, or doesn't it matter?它的rows_cols_size_应该设置为零,还是无关紧要? Normally a moved-from object should be left in a "valid but unspecified" state, whatever you decide that means for your class.通常,移动的对象应该处于“有效但未指定”状态,无论您决定对您的类意味着什么。 At a minimum, calling the destructor should be valid, and assigning it to something else should work as expected;至少,调用析构函数应该是有效的,并且将它分配给其他东西应该按预期工作; these are already the case.这些已经是这样了。

Since the getter isn't needed here, it's a separate question whether the public interface should include a getter at all, or if it should have a more convenient return type like just const T* or T* .由于这里不需要 getter,因此公共接口是否应该包含一个 getter,或者它是否应该有一个更方便的返回类型,比如const T*T* ,这是一个单独的问题。

Doing:正在做:

 template <typename _T>
    Matrix_<_T>& Matrix_<_T>::operator=(Matrix_&& _m) noexcept {
        rows_ = _m.rows_;
        cols_ = _m.cols_;
        size_ = rows_*cols_;
        data_ = std::move(_m.data_);
        return *this;
    }

Will fix the code.将修复代码。 You don't need to use getter function inside the class, only when you want to access the member outside the class.你不需要在类内部使用getter函数,只有当你想访问类外的成员时才需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 unique_ptr成员,私有拷贝构造函数与移动构造函数 - unique_ptr member, private copy constructor versus move constructor 如何使用“ get”方法返回类的私有std :: unique_ptr成员 - How do I use a “get” method to return a private std::unique_ptr member of a class unique_ptr,移动构造函数以及为什么总是尝试访问私有成员 - unique_ptr, move constructor, and why always attempt to access private member 如何在构造函数初始值设定项列表中初始化std :: unique_ptr对象的类成员std :: vector? - How do I initialize a class member `std::vector` of `std::unique_ptr` object in the constructor initializer list? 使用unique_ptr成员编写移动构造函数的正确方法(崩溃) - Correct way to write move constructor with unique_ptr member (crash) 将具有unique_ptr的类的构造函数复制到作为成员的抽象类 - Copy constructor for a class with unique_ptr to an abstract class as a member 如何在将原始指针移动到我的基类构造函数之前从 unique_ptr 中提取它 - How can I extract a raw pointer from a unique_ptr before moving it into my base class constructor 使用unique_ptr作为抽象基类中的私有成员 - Using a unique_ptr as a private member in an abstract base class 使用 operator() 从代理 class 返回 unique_ptr 成员变量 - Return unique_ptr member variable from proxy class with operator() 返回 std::move 带有 unique_ptr 成员的 class - return std::move a class with a unique_ptr member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM