在c ++中为类创建[] []运算符

时间:2015-06-28 09:01:54

标签: c++ operator-overloading

我正在为某人制作Pentago游戏,我想写一个好的代码,所以我决定使用运算符重载。

我们有2个班级;第一个是Block类(代表板的每个块),第二个是Set类(代表3 * 3块的块)。 现在我想使用Set作为2d数组,所以我可以使用set [foo] [foo]。 你能帮我做一个像这样的经营者吗?

5 个答案:

答案 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;
}