Arrays C+的设计+;动态数组
我正在为动态数组设计一些类(比如std::vector)。我不想使用STD::vector是因为我的C++程序经常被用作从C/C++ +Fortran/Delphi调用的库,因此将数组输入作为指针。出于安全原因,std::vector不能在构造时窃取指针。我的Array1D可以用作std::vector,但也可以用指针构造。不幸的是,Visual Studio 2013似乎担心我的设计。在提出问题之前,我需要解释一下这个设计 这是我的班级布局Arrays C+的设计+;动态数组,arrays,c++11,Arrays,C++11,我正在为动态数组设计一些类(比如std::vector)。我不想使用STD::vector是因为我的C++程序经常被用作从C/C++ +Fortran/Delphi调用的库,因此将数组输入作为指针。出于安全原因,std::vector不能在构造时窃取指针。我的Array1D可以用作std::vector,但也可以用指针构造。不幸的是,Visual Studio 2013似乎担心我的设计。在提出问题之前,我需要解释一下这个设计 这是我的班级布局 template <typename T>
template <typename T>
class Array1D {
private:
T* data_;
T* size_; // No stored as an int for optimisation purposes
bool owner_;
public:
Array1D(int n) {
data_ = new T[n];
size_ = data_ + n;
owner_ = true;
}
Array1D(T* data, int n) {
data_ = data;
size_ = data + n;
owner_ = false;
}
...
};
模板
类数组1d{
私人:
T*数据;
T*size_;//出于优化目的,No存储为int
布尔所有者;
公众:
阵列1D(内部n){
数据=新的T[n];
大小=数据+n;
所有者=真;
}
数组1d(T*数据,整数n){
数据=数据;
大小=数据+n;
所有者=假;
}
...
};
大多数情况下,它作为std::vector工作,并且owner_uu设置为true。还可以从指针构造Array1D,这次owner_uu设置为false。在这种情况下,不允许(通过断言)执行某些操作,例如调整大小。阵列A的复制构造函数和赋值设计为:
- Array1D(const Array1D&B):将B深拷贝到A中。构造后,A拥有其内存
- Array1D(Array1D&&B):所有情况下的移动操作。施工后,A的所有权状态与B相同
- operator=(const Array1D&B):B到A的深度复制。如果A不拥有其内存,则会有一个断言来检查A和B的大小是否相同。转让不会更改A的所有权状态
- 运算符=(Array1D&&B):如果A和B拥有内存,则移动操作。否则,我们进行深度复制,如果a不拥有内存,则使用断言检查大小。转让不会更改A的所有权状态
template <typename T>
class Array2D {
private:
T* data_;
T* size_[2];
bool owner_;
public:
Array2D(int n, int p) {
data_ = new T[n];
size_[0] = data_ + n;
size_[1] = data_ + p;
owner_ = true;
}
Array1D(T* data, int n, int p) {
data_ = data;
size_[0] = data + n;
size_[1] = data + p;
owner_ = false;
}
...
Array1D<T> operator()(int i) {
Array1D<T> row(data_ + i * nb_columns(), nb_columns());
return row;
}
...
int nb_columns() const {
return static_cast<int>(size_[1] - data_);
}
};
模板
类数组2d{
私人:
T*数据;
T*size_u2];
布尔所有者;
公众:
阵列2d(整数n,整数p){
数据=新的T[n];
大小_u0]=数据_n+n;
大小u[1]=数据p+p;
所有者=真;
}
数组1d(T*数据,整数n,整数p){
数据=数据;
大小_u0]=数据+n;
大小_u[1]=数据+p;
所有者=假;
}
...
Array1D运算符()(int i){
数组1d行(数据+i*nb_列(),nb_列());
返回行;
}
...
int nb_columns()常量{
返回静态\u转换(大小\u[1]-数据\u);
}
};
运算符()返回的Array1D(int i)不拥有内存,并且包含指向Array2D对象拥有的第i行的指针。在以下类型的代码中是有用的
sort(Array1D<T>& A); // A function that sorts array in place
Array2D<double> matrix(5, 100); // Construct an array of 5 rows and 100 columns
... // Fill the array
sort(matrix(3)) // Sort the 4th row
排序(Array1D&A);//对数组进行就地排序的函数
阵列2d矩阵(5100);//构造一个5行100列的数组
... // 填充数组
排序(矩阵(3))//对第4行进行排序
二维数组行的那些“临时视图”非常有用,但我更喜欢将它们限制为临时对象以限制别名
遗憾的是,使用VisualStudio 2013,我从IDE得到了以下的警告,即行排序(矩阵(3)):“将R值绑定到L值引用的选项是非标准微软C++扩展”。我知道矩阵(3)是一个暂时存在的对象,通过排序修改它看起来很奇怪。但是,由于它是一个“视图”,修改它会修改matrix拥有的内存,这是有用的
因此,我的问题如下:
- 这个设计有缺陷吗
是我正在做的C++有效吗?(修改临时值)
不是。非常量左值引用无法绑定到临时对象: 这个设计有缺陷吗 您正在修改包装在对象中的内容。因为您需要一个左值,所以只需通过一个中间变量来固定它:auto m_temp_lvalue = matrix(3); // get the 4th row
sort(m_temp_lvalue); // sort the 4th row
我希望这能有所帮助。您给出的
sort
原型采用的是值类型,而不是左值引用类型代码>实现?@ecatmut:谢谢您的评论。这篇文章已被编辑。@Ashalynd:谢谢你的评论。这篇文章已被编辑。@InsideLoop可能sort
只需要做一个r值参考?谢谢你的解释。即使你的中间变量想法可行,我最终还是决定避免那些“视图”,只有一个数组ID指向内存中的某个位置。它使事情更安全。