You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在HashTable类中正确声明Cell类型数组成员?

如何在HashTable类中正确定义Cell类型的数组成员?

问题描述

我创建了Cell和HashTable两个类,希望在HashTable类中声明一个Cell类型的数组成员,就像声明int类型的cars数组那样。尝试了两种声明方式但未能成功,调试时能看到cars数组,却看不到table数组。相关代码如下:

// Cell类代码
class Cell
{
public:
    AVLTree<Player*>* AllPlayers;
    int treeSize;
    Cell() : treeSize(0) {
         AllPlayers = new  AVLTree<Player*>();
    }

    ~Cell(){
        delete AllPlayers;
    };

    Cell(const Cell &sec) = default;
    Cell &operator=(const Cell &sec) = default;

    void reinsert(Player* pl)
    {
        treeSize++;
        AllPlayers->root = AllPlayers->insert(AllPlayers->root, pl,NULL);
    }

    int insert(Player* pl)
    {
        if (!(AllPlayers->findNode(AllPlayers->root,pl)))
        {
            AllPlayers->root = AllPlayers->insert(AllPlayers->root,pl,NULL);
            treeSize++;
            return 0;
        }
        return -1;
    }

    int remove(Player* pl)
    {
        AllPlayers->root = AllPlayers->remove(AllPlayers->root,pl);
        treeSize--;
        return  treeSize;
    }
};

// HashTable类代码
class HashTable{
    public:
    int size;
    int numOfKeys;
    Cell* table;
    int cars[4];
    static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
    HashTable() : size(10), numOfKeys(0) {
        table = new Cell[10];
    }
    ~HashTable() { delete[] table; }
};

解决方案

方案1:修复原生动态数组的内存安全问题

你的table声明和初始化语法本身是正确的,但存在浅拷贝导致的内存风险,这也可能影响调试器的正常显示。需要为HashTable禁用默认拷贝构造和赋值运算符,避免多个对象共享同一块Cell数组内存:

class HashTable{
public:
    int size;
    int numOfKeys;
    Cell* table;
    int cars[4];
    static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);

    HashTable() : size(10), numOfKeys(0) {
        table = new Cell[10]; // 自动调用10次Cell的默认构造函数初始化数组元素
    }

    ~HashTable() { 
        delete[] table; // 必须使用delete[]释放数组,不能用delete
    }

    // 禁用默认拷贝构造和赋值运算符,防止浅拷贝
    HashTable(const HashTable&) = delete;
    HashTable& operator=(const HashTable&) = delete;
};

调试时看不到table数组,可尝试在调试窗口中展开table变量后,手动指定数组长度(比如10),即可查看所有元素。

方案2:使用std::vector<Cell>替代原生指针(推荐)

原生动态数组需要手动管理内存,容易出错。使用C++标准库的std::vector可以自动处理内存分配和释放,调试器也能直接显示所有数组元素:

#include <vector> // 必须包含头文件

class HashTable{
public:
    int size;
    int numOfKeys;
    std::vector<Cell> table; // 用vector替代原生指针
    int cars[4];
    static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);

    HashTable() : size(10), numOfKeys(0), table(10) {
        // vector(10)会自动创建10个Cell对象,调用默认构造函数初始化
    }

    // 无需手动编写析构函数,vector会自动清理内存
};

额外修复:Cell类的深拷贝问题

你的Cell类使用了默认拷贝构造和赋值运算符,这会导致浅拷贝:多个Cell对象共享同一个AVLTree指针,析构时会重复释放内存导致崩溃。需要手动实现深拷贝:

class Cell
{
public:
    AVLTree<Player*>* AllPlayers;
    int treeSize;

    Cell() : treeSize(0) {
         AllPlayers = new AVLTree<Player*>();
    }

    ~Cell(){
        delete AllPlayers;
    };

    // 深拷贝构造函数
    Cell(const Cell &sec) : treeSize(sec.treeSize) {
        // 假设AVLTree类支持拷贝构造,如果不支持需要手动实现AVL树的拷贝逻辑
        AllPlayers = new AVLTree<Player*>(*sec.AllPlayers);
    }

    // 深拷贝赋值运算符
    Cell &operator=(const Cell &sec) {
        if (this != &sec) { // 防止自赋值
            delete AllPlayers; // 先释放当前对象的AVL树
            treeSize = sec.treeSize;
            AllPlayers = new AVLTree<Player*>(*sec.AllPlayers); // 拷贝新的AVL树
        }
        return *this;
    }

    // 其他成员函数保持不变
    void reinsert(Player* pl) { ... }
    int insert(Player* pl) { ... }
    int remove(Player* pl) { ... }
};

内容的提问来源于stack exchange,提问作者Algo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:35:21