Как хранить ссылку на класс в C ++? - PullRequest
0 голосов
/ 01 мая 2020

Итак, у меня есть этот код:

int cols = 5, rows = 5;

class Node
{
public:
    Node()
    {
        this->x = 0;
        this->y = 0;
    }

    Node(int i, int j)
    {
        this->x = i;
        this->y = j;
    }

    void AddNeighbors(Node** grid)
    {
        if (this->x < cols - 1)
        {
            this->neighbors.push_back(grid[this->x + 1][this->y]);
        }
        if (this->x > 0)
        {
            this->neighbors.push_back(grid[this->x - 1][this->y]);
        }
        if (this->y < rows - 1)
        {
            this->neighbors.push_back(grid[this->x][this->y + 1]);
        }
        if (this->y > 0)
        {
            this->neighbors.push_back(grid[this->x][this->y - 1]);
        }
    }

    int x;
    int y;
    vector<Node> neighbors;

    bool operator == (Node n2) 
    {
        return this->x == n2.x && this->y == n2.y;
    }

    bool operator != (Node n2) 
    {
        return this->x != n2.x && this->y != n2.y;
    }
};

void RemoveFromVector(vector<Node> &nodesSet, Node element)
{
    vector<Node>::iterator it = nodesSet.begin();

    for (int i = nodesSet.size() - 1; i >= 0; i--)
    {
        if (nodesSet[i] == element)
        {
            advance(it, i);
            nodesSet.erase(it);
            break;
        }
    }
}

bool ExistsInVector(vector<Node>& nodesSet, Node element)
{
    for (int i = 0; i < nodesSet.size(); i++)
    {
        if (nodesSet[i] == element)
        {
            return true;
        }
    }

    return false;
}

int main()
{
    Node** grid;

    grid = new Node* [cols];

    for (int i = 0; i < cols; i++)
    {
        grid[i] = new Node[rows];
        for (int j = 0; j < rows; j++)
        {
            Node node = Node(i, j);
            grid[i][j] = node;
        }
    }

    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            grid[i][j].AddNeighbors(grid);
        }
    }
}

И у меня много проблем, когда мне приходится хранить соседей, потому что они не относятся к ссылочному типу. В какой-то момент программы я должен получить доступ к соседям соседей, но у них нет соседей:)

Итак, я знаю, что я должен хранить соседей как ссылку, но это сломает в основном все (для Например, мне нужно перегрузить две функции: RemoveFromVector и ExistsInVector, чтобы им пришлось получить элемент Node * в качестве параметра). Может быть, можно создать класс Node в качестве ссылки, но он не сломает все?

UPD: у меня есть такие вопросы, потому что большую часть времени программирования я работал с Ruby, где в основном все ссылка и данный код определенно будут работать в Ruby.

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Я нашел решение самостоятельно, но чувствую, что это самый не-C ++ способ решения моей проблемы:

int cols = 5, rows = 5;

class Node
{
public:
    Node() : x(0), y(0)
    {
    }

    Node(int i, int j) : x(i), y(j)
    {
    }

    void AddNeighbors(Node*** grid)
    {
        if (this->x < cols - 1)
        {
            this->neighbors.push_back(grid[this->x + 1][this->y]);
        }
        if (this->x > 0)
        {
            this->neighbors.push_back(grid[this->x - 1][this->y]);
        }
        if (this->y < rows - 1)
        {
            this->neighbors.push_back(grid[this->x][this->y + 1]);
        }
        if (this->y > 0)
        {
            this->neighbors.push_back(grid[this->x][this->y - 1]);
        }
    }

    int x;
    int y;
    vector<Node *> neighbors;

    bool operator == (Node const & n2) const
    {
        return this->x == n2.x && this->y == n2.y;
    }

    bool operator != (Node const & n2) const
    {
        return this->x != n2.x && this->y != n2.y;
    }
};

int main()
{
    Node*** grid;

    grid = new Node** [cols];
    for (int i = 0; i < cols; i++)
    {
        grid[i] = new Node*[rows];        
        for (int j = 0; j < rows; j++)
        {
            grid[i][j] = new Node(i, j);
        }
    }

    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < rows; j++)
        {
            grid[i][j]->AddNeighbors(grid);
        }
    }
}
0 голосов
/ 01 мая 2020

Как правило, в c ++ лучше манипулировать контейнерными итераторами, а не ссылками / указателями в каждом элементе. Вместо функции-члена node.getNext () вы можете просто иметь ++ nodeIt и затем * nodeIt для доступа к нему. В вашем случае 2d матрицы вы должны разработать свой собственный итератор (см. пользовательский класс итератора ), чтобы реализовать ваши функции приращения в 4 направлениях (и защитить пограничные случаи в реализации). Как только это будет сделано, вы можете просто заставить эти функции возвращать конечный итератор, чтобы иметь возможность проверить, не сработал ли аванс.

Если вы действительно хотите использовать node.getRight / Left / Up / Down () В шаблоне вы можете хранить 4 указателя в каждом узле (не проприетарные, просто необработанные указатели) и передавать их nullptr, чтобы можно было проверить, нет ли следующего узла в нужном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...