[英]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.