重载运算符 [] 用于从对象数组中给出特定索引
overload operator [] to give a specific index from array of objects
我有类XOBoard
,它呈现了一个大小为 n*n 的数组,数组的每个单元格都是一个名为Cell
的对象。
每个 Cell 对象由
class Cell {
private:
char ch;
public:
Cell(char ch = '.');
char getCellValue();
void setCellValue(char nch);
};
董事会的定义是这样的:
class XOBoard {
private:
int n;
Cell **Board;
};
XOBoard::XOBoard(int n) { //constructor
this->n = (n >= 3) ? n : 3;
Board = new Cell*[n];
for (int i = 0; i < n; i++) {
Board[i] = new Cell[n];
}
}
我想使用此方法获取特定的 Cell 值:board1[{1,2}]
,但我想检查发送给我的值是否在范围 (n( 内,但不幸的是我无法进入 Board 数组,并n
变量。
这是代码:
XOBoard& operator[](list<int> list){
int x = list.front(), y = list.back();
return Board[x][y].getCellValue();
}
谢谢头!
如注释中所述,使用operator[]
进行多维下标是非常规的,但如果需要,则应确保获得正确数量的值(在本例中为 2(并返回正确的类型(在本例中为Cell&
(。
还要注意阴影。如果您尝试构造值小于 3 的Board
,则将this->n
设置为 3,但继续使用错误的n
(甚至可能是负值(进行构造。
更多内联评论:
#include <iostream>
#include <stdexcept>
#include <tuple>
class Cell {
private:
char ch;
public:
Cell(char nch = '.') : // after the colon comes the member initializer list
ch(nch) // which is usually good to use
{
// if(ch is not valid) throw ...
}
char getCellValue() const { return ch; }
// a convenient conversion operator to automatically
// convert a Cell to a char where a char is needed
// (like when streaming a Cell to std::cout)
operator char() const { return ch; }
// void setCellValue(char nch); // replaced by operator=
Cell& operator=(char nch) {
// if(nch is not valid) throw ...
ch = nch;
return *this;
}
};
class XOBoard {
private:
size_t n; // use an unsigned type for sizes/indices
Cell** Board;
public:
// constructor
XOBoard(size_t xy_size) : // a member initializer list again
n(xy_size >= 3 ? xy_size : 3), // assign to "n" here
Board(new Cell*[n]) // the correct n is now used
{
// if the below construction fails, a bad_alloc will be thrown.
// you need to add code to clean up what you've already allocated to take
// care of that situation.
for(size_t i = 0; i < n; i++) {
Board[i] = new Cell[n];
}
}
// Copying or moving need careful handling of the pointers.
// Read "The rule of three/five/zero". Until then, disable it.
XOBoard(const XOBoard&) = delete;
XOBoard& operator=(const XOBoard&) = delete;
// destructor
~XOBoard() {
for(size_t i = 0; i < n; i++) delete[] Board[i];
delete[] Board;
}
// added for convenience
size_t size() const { return n; }
// return a Cell& and use a std::pair since you
// expect exactly 2 values
Cell& operator[](std::pair<size_t, size_t> pos) {
auto& [x, y] = pos;
if(x>=n || y>=n)
throw std::out_of_range("{"+std::to_string(x)+","+std::to_string(y)+"}");
return Board[x][y];
}
};
int main() {
try {
XOBoard a{2}; // trying an invalid size
std::cout << a.size() << 'n';
a[{2, 2}] = 'a';
std::cout << a[{2, 2}] << 'n';
Cell x = 'b';
a[{2, 2}] = x;
std::cout << a[{2, 2}] << 'n';
a[{2, 3}] = 'c'; // index out of bounds
} catch(const std::out_of_range& ex) {
std::cerr << "out_of_range exception: " << ex.what() << 'n';
}
}
输出:
3
a
b
out_of_range exception: {2,3}
您应该尽量避免使用原始指针和实际的多维数组。通常,最好通过分配一维数组来模拟维度,并为用户提供一个接口来计算要处理的正确元素。
相关文章:
- 特征获取索引数组,其中向量中的值为真(不需要循环)
- 是否可以使用字符串或字符索引数组
- 为什么在使用字符索引数组时会出现这种不同的行为
- 在具有重复索引的索引数组处更改 ArrayFire 数组
- 使用索引数组订购 ArrayFire Array 的最佳方式
- C++ 中结构的动态索引数组
- 1索引数组上的qsort()正在扰乱索引
- C++ 索引数组打印和删除字符串名称 数组打印
- 字符串下标超出范围.我不知道如何使用字符索引数组,所以我使用了(无符号整数),但它不起作用
- openGL drawElements - 一个额外的三角形,使用索引数组
- 具有索引数组的地形(高度贴图)LOD
- 通过创建索引数组进行 C++ 排序
- OpenGL:两个顶点数组 + 两个索引数组
- 将索引数组排序为主数组
- 自动循环跳过某些索引数组
- 为静态强制转换的索引数组生成数组
- 重载枚举索引数组的std::get
- 使用c++中的第二个索引数组对数组进行排序
- 给定的零索引数组 &该数组的均衡索引
- CUDA:重新索引数组