在 c++ 中为类创建 [][] 运算符
Creating [][] operator for class in c++
我正在为某人制作一个 Pentago 游戏,我想写一个好的代码,所以我决定使用运算符重载。
我们有 2 个类;第一个是块类(代表电路板的每个块(,第二个是 Set 类(代表 3*3 块表(。现在我想将 Set 用作 2d 数组,以便我可以使用 set[foo][foo]。你能帮我做一个这样的运算符吗?
一个非常简单的解决方案是
struct MyClass {
int x[3][3];
int* operator[](int row) { return &(x[row][0]); }
};
即从operator[]
返回element*
。
这允许使用
myinstance[row][col]
(至少(有两种方法可以去这里。
首先是制作类似 set_row
类的东西,这是一个代理。所以你会有类似的东西
class set
{
public:
set_row operator[](size_t row)
{
// Return a proxy object that just sees the correct row.
return set_row(internal_buffer_pointer[row]);
}
...
};
set_row
是这样的
class set_row
{
public:
// Ctor takes a row
// Take a column, and return a reference to the correct column in the row.
element &operator[](size_t column);
};
根据经验(on,咳咳,VisualC ++(,这很慢,因为它需要为每个访问构造一个代理对象。
二是放弃operator[]
,使用operator()
:
class set
{
public:
element &operator()(size_t row, size_t col);
...
};
使用operator[]
会很好,但不幸的是,你不能用它做到这一点。
没有operator[][]
.如果要提供这些语义,则需要重载operator[]
以便它返回另一个也重载operator[]
的对象。
您的案例可以使用向量向量来解决:
#include <vector>
#include <cstdint>
#include <iostream>
struct Block
{
int value = 0;
};
class Set
{
std::vector<std::vector<Block> > grid;
public:
Set(): grid(3, std::vector<Block>(3)) {} // 3 x 3
std::vector<Block>& operator[](std::size_t x) { return grid[x]; }
};
int main()
{
using std::size_t;
Set set;
set[1][1].value = 1;
for(size_t x = 0; x < 3; ++x)
{
for(size_t y = 0; y < 3; ++y)
{
std::cout << set[x][y].value << ' ';
}
std::cout << 'n';
}
}
输出:
0 0 0
0 1 0
0 0 0
这是有效的,因为Set::operator[]
返回对std::vector
的引用,并且std::vector
重载operator[]
返回对Block
的引用。
无法为类提供operator[][]
。
但是,如果您的Set
提供operator[]()
,则该运算符可以返回对其他具有operator[]()
的引用。
例如;
class Row
{
public:
Block &operator[](int block_no) {return data[block_no];};
private:
std::vector<Block> data;
};
class Set
{
public:
Row &operator[](int row_no) {return row[row_no];};
private:
std::vector<Row> row;
};
int main()
{
Set s;
// assume s is set up appropriately
Block b = s[2][3]; // equivalent to s.operator[](2).operator[](3)
}
显然,还需要进行相关的错误检查,正确设置类的内容等。
假设内存是连续的,则可以返回指向行的第一个元素的指针。
工作示例
#include <iostream>
class MyType
{
public:
static const size_t rows = 3;
static const size_t columns = 3;
static const size_t size = rows * columns;
MyType()
{
for(size_t index = 0; index < 9; ++index)
{
data[index] = index;
}
}
int* operator[](size_t index)
{
return &data[rows * index];
}
private:
int data[size];
};
int main()
{
MyType instance;
std::cout << instance[2][1] << std::endl;
}
相关文章:
- 如何使用新运算符跟踪在循环中创建的 QLabel
- 如何创建运算符重载?
- 为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
- 如何在C++中使用 new 运算符创建对动态创建的数组的引用?
- 使用新运算符C++创建多维数组的简单方法
- 为字典cpp创建[]=运算符
- 创建变量之间的运算符排列
- 如何从模板类重载创建的指针对象上的运算符?
- 为什么map使用运算符[]创建新条目
- 赋值运算符创建指针,无法删除
- 通过数组和"new"运算符创建的对象,但如何传递参数?
- 从初始化构造函数和赋值运算符创建的对象有什么区别
- 正在使用overriden new[]运算符创建字符串数组
- 使用模板运算符创建二维关联阵列
- 尝试使用重载运算符创建新的事件处理程序>>迷失了自己试图找出所需的语法
- 使用重载'*'运算符创建多个副本
- 使用基类的运算符>>创建派生类
- 如何使用运算符[]创建模拟类
- new 运算符 - 创建对象指针数组 C++
- 读取使用运算符创建的矩阵