我正在为某人制作Pentago游戏,我想写一个好的代码,所以我决定使用运算符重载。
我们有2个班级;第一个是Block类(代表板的每个块),第二个是Set类(代表3 * 3块的块)。 现在我想使用Set作为2d数组,所以我可以使用set [foo] [foo]。 你能帮我做一个像这样的经营者吗?
答案 0 :(得分:3)
至少有两种方法可以去这里。
第一个是制作类似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,ahem,VisualC ++),这是慢,因为它需要为每次访问构建一个代理对象。
第二种是放弃operator[]
,并使用operator()
:
class set
{
public:
element &operator()(size_t row, size_t col);
...
};
使用operator[]
会很不错,但不幸的是,你无法用它做到这一点。
答案 1 :(得分:3)
一个非常简单的解决方案是
struct MyClass {
int x[3][3];
int* operator[](int row) { return &(x[row][0]); }
};
即。从element*
返回operator[]
。
这允许使用
myinstance[row][col]
答案 2 :(得分:1)
无法为班级提供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)
}
显然,还需要进行相关的错误检查,正确设置类的内容等。
答案 3 :(得分:1)
没有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
的引用。
答案 4 :(得分:0)
假设内存是连续的,您可以返回指向该行的第一个元素的指针。
<强> Working example 强>
#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;
}