std :: vector和/或多态性问题

时间:2019-01-22 11:02:52

标签: c++ visual-studio-2017

我到处都在寻找答案,但找不到答案。以下是我在Visual Studio 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 :(得分:1)

这不应该首先编译(here's why),但是由于您的编译器显然允许它...

您要存储临时对象的地址:

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

在表达式结束后,在此表达式中创建的Maze对象立即死亡,并且留下了悬空的指针,没有特别指向的地方。

通常不需要将指针存储在向量中,除非您想要多态行为。在这种情况下,请使用合适的智能指针,例如shared_ptrunique_ptr

答案 1 :(得分:1)

问题是这样的:rooms.push_back(&Maze(i, j, v))

问题是当前对象分配在堆栈上,并且在此行之后,该对象将被破坏。

Room*切换到Room并不是解决方案-如果这样做,您将无法实现多态。

最佳解决方案: rooms.push_back(new Maze(i, j, v))

注意: 您需要定义三个规则,因为存在共享内存。 当您执行pop_back时,请先在房间的当前元素上调用运算符delete,然后调用pop_back的{​​{1}}方法。