在const 2D数组上支持my_2D_Array[x][y](双运算符[]);无法使事情正常工作
Supporting my_2D_Array[x][y] (double operator[]) on a const 2D array; Cannot get things working
我正在C++中创建一个2D数组类。对于非成本数组,一切都很好。我还没有找到一个很好的解释const函数,似乎总是在摸索,直到它起作用。然而,现在,我陷入了困境。
我是否不了解如何支持const对象?除了创建第二个Row类,我想不出解决方案,而且这个解决方案似乎没有必要。
main.cpp
#include "Array2D.h"
int main()
{
int const x(1), y(1);
Array2D<int> arr(3, 3);
int value(0);
for (int row(0); row < 3; ++row)
for (int column(0); column < 3; ++column)
arr[row][column] = ++value;
std::cout << arr[x][y];
Array2D<int> const carr(arr);
//Everything's fine up to here
std::cout << carr[x][y]; //Error
std::cout << "nn[ PAUSE: Press ENTER to exit the program. ]";
std::cin.get();
return 0;
}
当我试图访问carr[x][y]时,它会抛出一个错误,这是意料之中的。所以我在Array2D 中包含了运算符[]的常量和非常量重载
阵列2D.h
template <typename T>
class Array2D
{
public:
//===============
//CONSTRUCTORS
//
inline Array2D();
inline Array2D(int rows, int columns = 0);
inline Array2D(Array2D const &array2D);
//===============
//OPERATORS
//
inline Array2D<T>& operator=(Array2D const &array2D);
inline Row<T> operator[](int index);
inline Row<T> const operator[](int index) const;
//===============
//GETTERS
//
inline int getRows() const { return _rows; }
inline int getColumns() const { return _columns; }
//===============
//SETTERS
//
inline void setRows(int rows); //May result in loss of data
inline void setColumns(int columns); //May result in loss of data
//OTHER
inline T& select(int row, int column);
inline T const & select(int row, int column) const;
//===============
//DESTRUCTOR
//
inline ~Array2D(){}
private:
//===============
//DATA
//
Array<T> _array; //Two dimensional array in row-major order
int _rows; //The number of rows in the array
int _columns; //The number of data in each row
//===============
//PRIVATE FUNCTIONS
//
//Initializes the array with current data
inline void initArray2D();
//Throws exception if length is negative
inline void checkLength(int length) const;
//Throws exception if index is out of bounds
inline void checkIndex(int rowIndex, int columnIndex) const;
};
//CONSTRUCTORS
template <typename T>
Array2D<T>::Array2D() : _array(0), _rows(0), _columns(0)
{ initArray2D(); }
template <typename T>
Array2D<T>::Array2D(int rows, int columns) : _array(0), _rows(rows), _columns(columns)
{
checkLength(rows);
checkLength(columns);
initArray2D();
}
template <typename T>
Array2D<T>::Array2D(Array2D const &array2D)
{ (*this) = array2D; }
//OPERATORS
template <typename T>
Array2D<T>& Array2D<T>::operator=(Array2D const &array2D)
{
_rows = array2D._rows;
_columns = array2D._columns;
initArray2D();
_array = array2D._array;
return *this;
}
template <typename T>
Row<T> Array2D<T>::operator[](int index)
{
return Row<T>(*this, index);
}
template <typename T>
Row<T> const Array2D<T>::operator[](int index) const
{
Row<T> const toReturn(*this, index);;
return toReturn;
}
//SETTERS
template <typename T>
void Array2D<T>::setRows(int rows)
{
_array.setLength(rows * _columns);
}
template <typename T>
void Array2D<T>::setColumns(int columns)
{
Array newArray(_rows * columns);
//This will prevent truncated columns from being copied over
int lesserColumn(columns > _columns ? _columns : columns);
for (int row(0); row < _rows; ++row)
for (int column(0); column < lesserColumn; ++column)
newArray[row][column] = _array[row][column];
_array = newArray;
}
//OTHER
template <typename T>
T& Array2D<T>::select(int row, int column)
{
checkIndex(row, column);
return _array[(row * column) + column];
}
template <typename T>
T const & Array2D<T>::select(int row, int column) const
{
checkIndex(row, column);
return _array[(row * column) + column];
}
// PRIVATE \
template <typename T>
void Array2D<T>::initArray2D()
{
_array = Array<T>(_rows * _columns);
}
template <typename T>
void Array2D<T>::checkLength(int length) const
{
if (length < 0)
throw Exception("LENGTH_LESS_THAN_ZERO");
}
template <typename T>
void Array2D<T>::checkIndex(int rowIndex, int columnIndex) const
{
if (rowIndex >= _rows || columnIndex >= _columns)
throw Exception("INDEX_LARGER_THAN_UPPER_BOUND");
if (rowIndex < 0 || columnIndex < 0)
throw Exception("INDEX_SMALLER_THAN_LOWER_BOUND");
}
const函数似乎是有序的,但是当它试图创建Row对象(在下一段中解释)时会出现问题,因为它期望Array2D&,但是在const函数中,它传递const Array2D&,这自然不起作用。
Row对象的思想是返回一些东西来处理第二个[]运算符,而不必返回数组。
第h行
template <typename T>
class Array2D;
template <typename T>
class Row
{
public:
//==============
//CONSTRUCTOR
//
inline Row(Array2D<T> &array2D, int row);
//==============
//OPERATORS
//
//The index will be validated by Array2D
inline T& operator[](int column);
inline T const & operator[](int column) const;
private:
//==============
//Data
//
Array2D<T>& _array2D; //Source array
int _row; //The row index
};
template <typename T>
Row<T>::Row(Array2D<T> &array2D, int row) : _array2D(array2D), _row(row)
{ }
template <typename T>
T& Row<T>::operator[](int column)
{
return _array2D.select(_row, column);
}
template <typename T>
T const & Row<T>::operator[](int column) const
{
return _array2D.select(_row, column);
}
这是Array.h供参考
#pragma once
#include "Exception.h"
template <typename T>
class Array
{
public:
//===============
//CONSTRUCTORS
//
inline Array();
inline Array(int length, int startIndex = 0);
inline Array(Array const ©);
//===============
//OPERATORS
//
inline Array& operator=(Array const ©);
inline T& operator[](int index);
inline T const & operator[](int index) const;
//===============
//GETTERS
//
inline int getStartIndex() const { return _startIndex; }
inline int getLength() const { return _length; }
//===============
//SETTERS
//
inline void setStartIndex(int index);
inline void setLength(int length);
//===============
//DECONSTRUCTOR <coolface.jpg>
//
inline ~Array();
private:
//===============
//DATA
//
T* _array; //Pointer to array of type T
int _length; //Length of the array
int _startIndex;
//===============
//PRIVATE FUNCTIONS
//
//Initializes the array with current LENGTH
inline void init();
//Throws exception if length is less than zero
inline void checkLength(int length) const;
//Throws exception if index is out of bounds
inline void checkIndex(int index) const;
//Copies contents of SOURCE to DESTINATION
inline void copyArray(T * destination, T * source, int lastIndex);
};
//CONSTRUCTORS
template <typename T>
Array<T>::Array() : _array(0), _length(0), _startIndex(0)
{ init(); }
template <typename T>
Array<T>::Array(int length, int startIndex = 0) : _array(0), _length(length), _startIndex(startIndex)
{
checkLength(length);
init();
}
template <typename T>
Array<T>::Array(Array const ©)
{ (*this) = copy; }
//OPERATORS
template <typename T>
Array<T>& Array<T>::operator=(Array const ©)
{
_length = copy._length;
_startIndex = copy._startIndex;
init();
copyArray(_array, copy._array, _length);
return *this;
}
template <typename T>
T& Array<T>::operator[](int index)
{
checkIndex(index);
return _array[index - _startIndex];
}
template <typename T>
T const & Array<T>::operator[](int index) const
{
checkIndex(index);
return _array[index - _startIndex];
}
//SETTERS
template <typename T>
void Array<T>::setStartIndex(int index)
{ _startIndex = index; }
// ! WARNING: Setting length to a lower value than current will result in lost data
template <typename T>
void Array<T>::setLength(int length)
{
checkLength(length);
T* oldArray(_array);
int oldLength(_length);
_length = length;
init();
int lastIndex(oldLength < _length ? oldLength : _length);
copyArray(_array, oldArray, lastIndex);
delete [] oldArray;
}
//DECONSTRUCT <coolface.jpg>
template <typename T>
Array<T>::~Array()
{
delete [] _array;
}
// PRIVATE \
template <typename T>
void Array<T>::init()
{
_array = new T[_length];
}
template <typename T>
void Array<T>::checkLength(int length) const
{
if (length < 0)
throw Exception("LENGTH_LESS_THAN_ZERO");
}
template <typename T>
void Array<T>::checkIndex(int index) const
{
if (index - _startIndex >= _length)
throw Exception("INDEX_LARGER_THAN_UPPER_BOUND");
if (index - _startIndex < 0)
throw Exception("INDEX_SMALLER_THAN_LOWER_BOUND");
}
template <typename T>
void Array<T>::copyArray(T * destination, T * source, int lastIndex)
{
while (lastIndex--)
destination[lastIndex] = source[lastIndex];
}
遗憾的是,我认为您需要两个版本的Row
:一个用于const Array
,一个用于非常数。就像标准容器有iterator
s和const_iterator
s一样。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 2D数组来自文本输入,中间有空格
- 将值指定给向量(2D)的向量中的某个位置
- 如何使用用户输入在C++中正确填充2D数组
- 导入库可以跨dll版本工作吗
- 如何在C++中检查2D数组中负值的输入验证
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 在2D伊辛模型上工作。C++新手。我在第 23 行收到错误"expected unqualified-id before '{' token"
- 2d循环OpenCl程序不工作
- C++ 2D 矢量清除按预期工作
- OpenGL 2d纹理无法工作
- 在const 2D数组上支持my_2D_Array[x][y](双运算符[]);无法使事情正常工作
- 修复了windows 7制作的2D数组在windows 10c++上的工作
- 在glUniformMatrix4fv, c++中2d数组工作吗?
- GLSL 2D旋转矩阵不像预期的那样工作