如何用C++创建类对象指针的动态二维向量以实现文本游戏随机地图?
嘿,我懂你这种想自己啃下来的心态——现成工具虽好,但亲手实现一遍才能真的搞懂指针和vector的玩法!毕竟你一年没碰C++,捡起来确实需要点循序渐进的引导,咱们一步步来:
第一步:先定义你的地图单元格类
首先得有个基础的单元格类,比如包含地图格子的核心属性(类型、是否可通行之类的),举个简单例子:
#include <vector> #include <cstdlib> #include <ctime> // 如果用智能指针还要加这个:#include <memory> // 定义你的单元格类 class Cell { public: enum Type { FLOOR, WALL, TREASURE }; Type type; Cell() : type(FLOOR) {} // 默认初始化为地板 };
第二步:初始化存储类指针的二维vector
核心就是vector<vector<Cell*>>——这是一个「装着vector的vector」,每个内层vector代表地图的一行,里面的元素是指向Cell对象的指针。
初始化有两种常用方式:
方式1:直接指定行列大小(适合固定尺寸的地图)
int main() { // 先确定地图的行列数,比如10行15列 const int MAP_ROWS = 10; const int MAP_COLS = 15; // 初始化二维vector,每个元素默认是nullptr(空指针) std::vector<std::vector<Cell*>> gameMap(MAP_ROWS, std::vector<Cell*>(MAP_COLS, nullptr)); // 后面的填充操作... }
方式2:动态添加行(适合行列数需要运行时确定的情况)
std::vector<std::vector<Cell*>> gameMap; // 先添加指定数量的行 for (int i = 0; i < MAP_ROWS; ++i) { // 每行初始化包含MAP_COLS个空指针 gameMap.push_back(std::vector<Cell*>(MAP_COLS)); }
第三步:填充随机地图内容
现在可以遍历每个格子,创建Cell对象并随机设置属性了。记得先初始化随机种子,不然每次运行的随机结果都会一模一样:
// 初始化随机种子(放在main函数开头) std::srand(std::time(nullptr)); // 遍历所有格子,填充随机内容 for (int row = 0; row < MAP_ROWS; ++row) { for (int col = 0; col < MAP_COLS; ++col) { // 创建一个Cell对象,把指针存到vector里 gameMap[row][col] = new Cell(); // 随机设置格子类型:比如30%概率是墙,10%是宝藏,剩下是地板 int randVal = std::rand() % 10; if (randVal < 3) { gameMap[row][col]->type = Cell::WALL; } else if (randVal == 9) { gameMap[row][col]->type = Cell::TREASURE; } } }
第四步:千万别忘了内存清理!
因为用了new创建对象,这些内存不会自动释放,必须手动delete,不然会造成内存泄漏:
// 遍历所有格子,释放每个Cell对象 for (auto& row : gameMap) { // 用引用避免拷贝整个行,提升效率 for (Cell* cell : row) { delete cell; cell = nullptr; // 好习惯,避免野指针 } } // 最后可以清空vector(可选,程序结束时vector会自动销毁自身内存) gameMap.clear();
进阶:用智能指针避免手动管理内存
如果觉得手动delete太麻烦、容易忘,可以用std::unique_ptr(智能指针的一种),它会在自身销毁时自动释放指向的对象,更安全省心:
// 定义二维vector时改用unique_ptr std::vector<std::vector<std::unique_ptr<Cell>>> gameMap(MAP_ROWS, std::vector<std::unique_ptr<Cell>>(MAP_COLS)); // 填充时用make_unique创建对象 gameMap[row][col] = std::make_unique<Cell>(); // 不需要手动delete!当gameMap销毁时,所有unique_ptr会自动释放Cell对象
对比你之前头疼的二维数组指针
你之前尝试的二维数组指针写法是Cell** gameMap = new Cell*[MAP_ROWS];,然后还要循环给每行分配gameMap[i] = new Cell[MAP_COLS];,释放的时候要先循环delete每行,再delete行数组,步骤多还容易出错。而vector帮你管理了外层和内层数组的内存,你只需要关心里面指针指向的对象,是不是简单多了?
内容的提问来源于stack exchange,提问作者RLee
相关产品推荐
相关产品推荐

