Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays C+的设计+;动态数组_Arrays_C++11 - Fatal编程技术网

Arrays C+的设计+;动态数组

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>

我正在为动态数组设计一些类(比如std::vector)。我不想使用STD::vector是因为我的C++程序经常被用作从C/C++ +Fortran/Delphi调用的库,因此将数组输入作为指针。出于安全原因,std::vector不能在构造时窃取指针。我的Array1D可以用作std::vector,但也可以用指针构造。不幸的是,Visual Studio 2013似乎担心我的设计。在提出问题之前,我需要解释一下这个设计

这是我的班级布局

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++有效吗?(修改临时值)
  • 这个设计有缺陷吗
注:完整代码可在上获得

是我正在做的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指向内存中的某个位置。它使事情更安全。