运算符重载[][]2d数组c++

operator overloading [][] 2d array c++

本文关键字:c++ 数组 2d 运算符 重载      更新时间:2023-10-16

我有一个2D数组,我想定义一个函数,该函数返回用户使用运算符重载给我的索引值。换句话说:

void MyMatrix::ReturnValue()
{
    int row = 0, col = 0;
    cout << "Return Value From the last Matrix" << endl;
    cout << "----------------------------------" << endl;
    cout << "Please Enter the index: [" << row << "][" << col << "] =" << ((*this).matrix)[row][col] << endl;
}

操作((*this).matrix)[row][col]应该返回一个int。我不知道如何构建operator [][]
或者,我可以将几个对operator []的调用连接起来,但我没有成功,因为对该操作器的第一个调用将返回int*,第二个调用将返返回int,这将强制构建另一个运算符,我不想这样做。

数据矩阵的定义类似

int** matrix; matrix = new int*[row];
if (matrix == NULL)
{
    cout << "Allocation memory - Failed";
}
for (int i = 0; i < row; i++)//Allocation memory
{
    matrix[i] = new int[col];
    if (matrix[i] == NULL)
    {
        cout << "Allocation memory - Failed";
        return;
    }
}

我能做什么?谢谢你,

简单地说,这样的运算符不存在,所以你不能重载它。

一个可能的解决方案是定义两个类:矩阵
您可以定义Matrixoperator[],使其返回Row,然后为Row定义相同的运算符,使它返回实际值(int或任何您想要的,您的Matrix也可以是一个模板)
这样,声明myMatrix[row][col]将是合法的和有意义的。

为了将新的CCD_ 14分配给CCD_。

*编辑*

正如评论中所建议的,在这种情况下,您还应该考虑使用operator()而不是operator[]
这样,就不再需要Row类了。

您可以为类定义自己的operator []。一个简单的方法可以看起来像

#include <iostream>
#include <iomanip>
struct A
{
    enum { Rows = 3, Cols = 4 };
    int matrix[Rows][Cols];
    int ( & operator []( size_t i ) )[Cols]
    {
        return matrix[i];
    }
};
int main()
{
    A a;
    for ( size_t i = 0; i < a.Rows; i++ )
    {
        for ( size_t j = 0; j < a.Cols; j++ ) a[i][j] = a.Cols * i + j;
    }

    for ( size_t i = 0; i < a.Rows; i++ )
    {
        for ( size_t j = 0; j < a.Cols; j++ ) std::cout << std::setw( 2 ) << a[i][j] << ' ';
        std::cout << std::endl;
    }
}

程序输出为

 0  1  2  3 
 4  5  6  7 
 8  9 10 11 

我不知道如何构建operator [][]

有时可以使用不同的运算符,即():

int& Matrix::operator () (int x, int y)
{
    return matrix[x][y];
}
const int& Matrix::operator () (int x, int y) const
{
    return matrix[x][y];
}
int diagonal (const Matrix& m, int x)
{
    return m (x, x); // Usage.
}

优势

  • 不需要使用像RowColumn这样的"中间"类。

  • Row& Matrix operator (int);更好的控制,在CCD_25中,有人可以使用Row引用来插入一行,比如说,非法长度。如果Matrix应该表示一个矩形的东西(图像,代数中的矩阵),这是一个潜在的误差源。

  • 在高维中可能不那么乏味,因为operator[]需要所有低维的类。

缺点:

  • 不同寻常的不同语法。

  • 如果需要的话,不需要更容易地替换完整的行/列。但是,无论如何,如果使用行进行建模(反之亦然),替换列并不容易。

在任何一种情况下,如果在运行时维度的数量未知,都有利弊。

我正在寻找经过自检的数组替换。。。改进版本返回引用或NULL引用,并检查内部边界。

#include <iostream>
#include <iomanip>
template<typename T, int cols>
class Arr1
{
public:
    Arr1(T (&place)[cols]) : me(place) {};
    const size_t &Cols = cols;
    T &operator [](size_t i)
    {
        if (i < cols && this != NULL) return me[i];
        else {
            printf("Out of bounds !n");
            T *crash = NULL;
            return *crash;
        }
    }
private:
    T (&me)[cols];
};
template<typename T, int rows, int cols>
class Arr2
{
public:
    const size_t &Rows = rows;
    const size_t &Cols = cols;
    Arr2() {
        ret = NULL;
        for (size_t i = 0; i < rows; i++) // demo - fill member array
        {
            for (size_t j = 0; j < cols; j++) matrix[i][j] = cols * i + j;
        }
    }
    ~Arr2() {
        if (ret) delete ret;
    }
    Arr1<T, cols>(&operator [](size_t i))
    {
        if (ret != NULL) delete ret;
        if (i < rows) {
            ret = new Arr1<T, cols>(matrix[i]);
            return *ret;
        }
        else {
            ret = NULL;
            printf("Out of bounds !n");
            return *ret;
        }
    }
    //T(&MemberCheck)[rows][cols] = matrix;
private:
    T matrix[rows][cols];
    Arr1<T, cols> *ret;
};
template<typename T,int rows, int cols>
class Arr
{
public:
    const size_t &Rows = rows;
    const size_t &Cols = cols;
    T(&operator [](size_t i))[cols]
    {
        if (i < rows) return matrix[i];
        else {
            printf("Out of bounds !n");
            T(*crash)[cols] = NULL;
            return *crash;
        }
    }
    T (&MemberCheck)[rows][cols] = matrix;
private:
    T matrix[rows][cols];
};
void main2()
{
    std::cout << "Single object version:" << endl;
    Arr<int, 3, 4> a;
    for (size_t i = 0; i <= a.Rows; i++)
    {
        int *x = &a[i][0];
        if (!x) printf("Fill loop - %i out of bounds...n", i);
        else for (size_t j = 0; j < a.Cols; j++) a[i][j] = a.Cols * i + j;
    }
    for (size_t i = 0; i < a.Rows; i++)
    {
        for (size_t j = 0; j <= a.Cols; j++) {
            std::cout << std::setw(2) << a[i][j] << ' ';
            if (a.MemberCheck[i][j] != a[i][j])
                printf("Internal error !");
        }
        std::cout << std::endl;
    }
    std::cout << endl << "Double object version:" << endl;
    Arr2<int, 3, 4> a2;
    for (size_t i = 0; i < a2.Rows; i++)
    {
        for (size_t j = 0; j <= a2.Cols; j++) {
            int &x = a2[i][j];
            if (&x)
            {
                x++;
                std::cout << std::setw(2) << a2[i][j] << ' ';
                //if (&a2.MemberCheck[i][j] != &a2[i][j])
                //  printf("Internal error !");
            }
        }
    }
}

输出

Single object version:
Out of bounds !
Fill loop - 3 out of bounds...
 0  1  2  3  4
 4  5  6  7  8
 8  9 10 11 -858993460
Double object version:
 1  2  3  4 Out of bounds !
 5  6  7  8 Out of bounds !
 9 10 11 12 Out of bounds !

它在下面的程序中运行良好

#include<iostream>
using namespace std;
class A{
    public:
    int r,c;
    int** val;
    A()
    {
        r=0;c=0;val=NULL;
    }
    A(int row,int col)
    {
        r=row;c=col;
        int count=0;
        val=new int*[row];
        for(int i=0;i<r;i++){
            val[i]=new int[col];
            for(int j=0;j<c;j++){
                count++;
                val[i][j]=count;
            }
        }
    }
    int* &operator[](int index){
        return val[index];
    }
};
int main(void){
    A a(3,3);
    cout<<a[1][2];
    return 0;
}

这里a[1][2]首先计算a[1]->它将第二行返回为(int*)类型则读取为(int*)[2],返回该行的第三个元素。简而言之,

a[1][2]----->(a[1])[2]------>(val[1])[2]------>val[1][2]。