gpt4 book ai didi

arrays - C++动态数组的设计

转载 作者:行者123 更新时间:2023-12-04 16:09:13 26 4
gpt4 key购买 nike

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

这是我类(class)的布局

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

大多数时候,它作为 std::vector 工作,并且 owner_ 设置为 true。也可以从指针构造一个 Array1D,这一次 owner_ 设置为 false。在这种情况下,某些操作(例如调整大小)是不允许的(通过断言)。数组 A 的复制构造函数和赋值设计为:
  • Array1D(const Array1D& B) : B 到 A 的深拷贝。构造后,A 拥有它的内存。
  • Array1D(Array1D&& B) :所有情况下的移动操作。 build 完成后,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_);
    }
    };

    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

    二维数组行的那些“临时 View ”非常有用,但我更喜欢将它们限制为临时对象以限制别名。

    不幸的是,使用 Visual Studio 2013,我从 IDE 中收到以下针对行 sort(matrix(3)) 的警告:“将 r-value 绑定(bind)到 l-value 引用的选项是非标准的 Microsoft C++ 扩展”。我知道 matrix(3) 是一个暂时存在的对象,并且通过排序对其进行修改看起来很奇怪。但是,由于它是一个“ View ”,因此修改它会修改矩阵拥有的内存并且很有用。

    所以我的问题如下:
  • 我在做什么是有效的 C++ 吗? (修改临时值)
  • 这个设计有缺陷吗?

  • PS:完整代码可在 Github 获得.

    最佳答案

    Is what I am doing valid C++? (modifying a temporary value)



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

    Is there a flaw in this design?



    您正在修改包装在对象中的内容。由于您需要一个左值,因此只需通过一个中间变量来修复它:
    auto m_temp_lvalue = matrix(3); // get the 4th row
    sort(m_temp_lvalue); // sort the 4th row

    我希望它有所帮助。

    关于arrays - C++动态数组的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26605818/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com