c++ 将用户定义的类插入到映射中

c++ inseting User Defined class into map

本文关键字:插入 映射 用户 定义 c++      更新时间:2023-10-16

我已经环顾四周很长一段时间了,认为我已经将大部分部分放在一起,但我的代码仍然不起作用......

我有一张地图,

    map<Number, Entry> chainList;

和一个类号和条目,我们现在不会担心的条目,因为我很确定一半是正确的

in Number.h
class Number
{
    public:
    //Public Functions
        //Constructor/Destructor
        Number(int len);
        Number(string copy);
        Number(const unsigned char *copy, int len);
        Number(const Number& in);
        ~Number();
        .......
        .......
        friend void swap(Number& first, Number& second);    
        bool operator<(const Number& rhs) const;
        Number& operator=(Number &rhs);
        private:
            //our binary number array
            unsigned char *num;
            //hold the length used, and maxsize of the array
            int length;
};

然后

//in Number.cpp
Number::~Number()
{
    delete [] num;  
}
Number::Number(const Number& in)
{
length = in.length;
num = (unsigned char *) calloc(length, sizeof(unsigned char));
    for (int i = 0; i < length; i++)
    {
        num[i] = in.num[i];
    }   
}
bool Number::operator<(const Number& rhs) const
{
    if (this -> length > rhs.length)
    {
        return false;
    }
    for (int i = 0; i < this -> length; i++)
    {
        if (this -> num[i] > rhs.num[i])
        {
            return false;
        }
        else if (this -> num[i] < rhs.num[i])
        {
            return true;
        }
    }
    return false;
}
void swap(Number& first, Number& second)
{
        // enable ADL (not necessary in our case, but good practice)
       using std::swap;
        // by swapping the members of two classes,
        // the two classes are effectively swapped
        swap(first.length, second.length);
        swap(first.num, second.num);
}

Number& Number::operator=(Number &rhs)
{
    swap (*this, rhs);
    return *this;
}

但是当我尝试将项目插入地图时,我遇到了 seg 错误......

in Database.cpp
....
chainList.insert(pair<Number, Entry>(*(tempEntry -> msgHash),  *tempEntry));
.....

其中 tempEntry -> msgHash 是一个数字* - 动态分配

我的问题可能是什么? 另一种选择是我有一个类型转换并返回 C++ 字符串的函数,我的问题是 std::less_than 函数是否可以在语句中间处理空字符,我知道它按字典顺序工作,但它是否取决于第一个空?

我认为问题出在operator<()

if (this->length > rhs.length)
    return false;
for (int i = 0; i < rhs.length; i++)
    ....

看?如果rhs.length大于this->length则继续比较字节。但是您最多比较 rhs.length 个字节,这可能会溢出this->num,因为this->length小于或等于 rhs.length

我不确定您是否需要特定的排序顺序,但我会做这样的事情:

if (this->length > rhs.length)
    return false;
if (this->length < rhs.length)
    return true;
for (int i = 0; i < rhs.length; i++)
    ....

现在,当您到达循环时,您可以确定两个数组的长度相同。

更新:

您在operator=(Number &rhs)中还有另一个重要问题.此运算符不应修改右侧运算符。所以它应该是 operator=(const Number &rhs)operator=(Number rhs) ,但绝不像您的那样是非常量引用。

您正在尝试实现复制和交换习惯用法。你几乎做对了,正确的方法是:

Number& Number::operator=(Number rhs)
{
    swap (*this, rhs);
    return *this;
}

更新#2

您正在分配带有calloc()数组,但使用 delete[] 释放它。这是不确定的行为。分配了calloc()的内存用free()释放,分配了new[]的内存用delete[]释放。

我的建议是使用std::vector<unsigned char>来保存动态数组,并避免所有this->lengthdelete[]等。只需在向量上std::swap()即可完成。