C++动态数组的设计

Ins*_*oop 6 arrays c++11

我正在为动态数组设计一些类(类似于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;
    }
    ...
};
Run Code Online (Sandbox Code Playgroud)

大多数情况下,它作为std :: vector工作,owner_设置为true.也可以从指针构造一个Array1D,这次owner_设置为false.在这种情况下,不允许某些操作(例如调整大小)(通过断言).复制构造函数和数组A的赋值设计为:

  • Array1D(const Array1D&B):B的深层拷贝到A.构造之后,A拥有它的内存.
  • Array1D(Array1D && B):在所有情况下移动操作.施工后,A的所有权状态与B相同.
  • operator =(const Array1D&B):B的深拷贝到A.如果A不拥有其内存,则断言用于检查A和B是否具有相同的大小.分配不会更改A的所有权状态.
  • operator =(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_);
    }
};
Run Code Online (Sandbox Code Playgroud)

operator()(int i)返回的Array1D不拥有其内存,并包含指向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
Run Code Online (Sandbox Code Playgroud)

对于二维数组的行的那些"临时视图"非常有用,但我更喜欢将它们限制为临时对象以限制别名.

不幸的是,使用Visual Studio 2013,我从IDE获得以下警告,用于行排序(矩阵(3)):"将r值绑定到l值引用的选项是非标准的Microsoft C++扩展".我理解矩阵(3)是一个临时生活的对象,通过一种奇怪的方式修改它.但是,因为它是一个"视图",修改它会修改矩阵所拥有的内存并且很有用.

所以我的问题如下:

  • 我正在做有效的C++?(修改临时值)
  • 这个设计有缺陷吗?

PS:完整的代码可以在Github上找到.

LeC*_*Coc 0

我正在做的事情是有效的 C++ 吗?(修改临时值)

它不是。非常量左值引用不能绑定到临时对象: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

这个设计有缺陷吗?

您正在修改对象中包装的内容。由于您需要有一个左值,因此只需使用一个中间变量即可修复它:

auto m_temp_lvalue = matrix(3); // get the 4th row
sort(m_temp_lvalue); // sort the 4th row
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助。