Проблема с std :: vector и / или полиморфизмом - PullRequest
0 голосов
/ 22 января 2019

Я везде искал ответ, но не могу его найти. Ниже моя короткая программа в визуальной студии 2017 года. Он не печатает ни одну из «комнат», которые я добавил, - он публикует случайные значения. Код компилируется отлично. просто вывод неверный. Я думаю, что большая часть кода не имеет значения, я просто честно не знаю, ЧТО я сделал неправильно. Я думаю, что это, вероятно, в части вектора / наследования.

РЕДАКТИРОВАТЬ: решены быстро. Я вставил указатель локальной переменной на мой вектор. спасибо.

Room.h:

#pragma once
#include <vector>

class Room {
protected:
    int i;
    int j;
    int size;
    char** objs;

public:
    Room(int _i = 0, int _j = 0, int _size = 0);
    int get_i() const { return i; }
    int get_j() const { return j; }
    int get_size() const { return size; }
    char** get_objs() const { return objs; }
    virtual void make_room() = 0;
};

class Maze : public Room {
public:
    Maze(int _i, int _j, int _size);
    void make_room();
};

class Board {
    std::vector<Room*> rooms;

public:
    Board() {}
    void add_room(int i, int j, int v);
    void print_a_room() const;
};

Room.cpp:

#include "room.h"
#include <iostream>

Room::Room(int _i, int _j, int _size) : i(_i), j(_j), size(_size) {
    objs = new char*[_size];
    for (int i = 0; i < _size; i++) {
        objs[i] = new char[_size];
        for (int j = 0; j < _size; j++) {
            objs[i][j] = ' ';
        }
    }
}

Maze::Maze(int _i, int _j, int _size) : Room(_i, _j, _size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            objs[i][j] = '*';
        }
    }
    make_room();
}

void Maze::make_room() {
    int x = 1;
}

void Board::add_room(int i, int j, int v) {
    rooms.push_back(&Maze(i, j, v));
}

void Board::print_a_room() const {
    Room* r = rooms.back();
    std::cout << r->get_i() << "," << r->get_j() << std::endl;
}

main.cpp:

#include "room.h"
#include <iostream>

int main() {
    Board b;
    b.add_room(1, 2, 10);
    std::cout << "hello" << std::endl;
    b.add_room(3, 4, 5);
    b.print_a_room();
    return 0;
}

Помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Проблема заключается в следующем: rooms.push_back(&Maze(i, j, v))

Проблема в том, что текущий объект размещен в стеке, и после этой строки этот объект будет уничтожен.

Переход с Room* на Room НЕ является решением - у вас не будет полиморфизма, если вы это сделаете.

Лучшее решение: rooms.push_back(new Maze(i, j, v)).

Примечание: Вам нужно определить правило трех, потому что есть общая память. Когда вы делаете pop_back, сначала вызовите оператора delete для текущего элемента комнаты, затем вызовите pop_back метод std::vector.

0 голосов
/ 22 января 2019

Это не должно компилироваться в первую очередь (, вот почему ), но поскольку ваш компилятор, очевидно, позволяет это ...

Вы храните адреса временных объектов:

void Board::add_room(int i, int j, int v) {
    rooms.push_back(&Maze(i, j, v));   // <---- There
}

Объекты Maze, созданные в этом выражении, умирают сразу после окончания выражения, и у вас остаются висячие указатели, указывающие ни на что конкретно.

Обычно хранить указатели ввектор, если вы не хотите полиморфное поведение.В этом случае используйте подходящий интеллектуальный указатель, например shared_ptr или unique_ptr.

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