C++ 类对象不工作的Linkedlist模板

C++ 类对象不工作的Linkedlist模板,c++,class,templates,data-structures,linked-list,C++,Class,Templates,Data Structures,Linked List,我已经创建了这个Dictionary类和一个Linkedlist模板,它将这个类作为类型。在main()函数中,我尝试创建Dictionary类的对象,并将Dictionary作为Linkedlist模板的类型传递。稍后,当我将创建的Dictionary类对象传递给LinkedList的insertHead()或initHead()函数,并尝试通过访问head的数据并调用Dictionary成员函数print()来打印数据时,它不会打印数据(32,A)。insertHead()打印一个“0-”,

我已经创建了这个Dictionary类和一个Linkedlist模板,它将这个类作为类型。在main()函数中,我尝试创建Dictionary类的对象,并将Dictionary作为Linkedlist模板的类型传递。稍后,当我将创建的Dictionary类对象传递给LinkedList的insertHead()或initHead()函数,并尝试通过访问head的数据并调用Dictionary成员函数print()来打印数据时,它不会打印数据(32,A)。insertHead()打印一个“0-”,initHead()给出分段错误。有没有办法解决这个问题

class Dictionary {
public:
    int index;
    string data;
public:
    Dictionary(int index = 0, string data = ""){
        this->index = index;
        this->data = data;
    }

    Dictionary(string data){
        this->data = data;
    }

    void setIndex(int index){
        this->index = index;
    }

    void setData(string data){
        this->data = data;
    }

    Dictionary operator=(Dictionary const & obj){
        Dictionary dict;
        dict.index = obj.index;
        dict.data = obj.data;
        return dict;
    }

    void print(){
        cout << index << "-" << data << endl;
    }

    friend bool operator== (const Dictionary &d1, const Dictionary &d2);
    friend bool operator!= (const Dictionary &d1, const Dictionary &d2);
};

bool operator== (const Dictionary &d1, const Dictionary &d2){
    return (d1.data == d2.data);
}

bool operator!= (const Dictionary &d1, const Dictionary &d2){
    return !(d1 == d2);
}


int main(){
    Dictionary d(32, "A");
    LinkedList<Dictionary> l;
    l.insertHead(d);
    l.head->data.print();
}
类字典{
公众:
整数指数;
字符串数据;
公众:
字典(int索引=0,字符串数据=”){
这个->索引=索引;
这->数据=数据;
}
字典(字符串数据){
这->数据=数据;
}
无效集合索引(整数索引){
这个->索引=索引;
}
void setData(字符串数据){
这->数据=数据;
}
字典运算符=(字典常量和对象){
词典词典;
dict.index=obj.index;
dict.data=obj.data;
返回命令;
}
作废打印(){
cout数据=项目;
}
无效插入头(T项){
Node*tmp=新节点();
if(head==nullptr){
水头=tmp;
head->prev=nullptr;
头部->数据=项目;
head->next=nullptr;
tail=tmp;
}否则{
tmp->next=头部;
tmp->data=物料;
tmp->prev=nullptr;
head->prev=tmp;
水头=tmp;
}
}
无效插入最后一个(T项){
Node*tmp=新节点();
tmp->data=物料;
if(head==nullptr){
水头=tmp;
head->prev=nullptr;
head->next=nullptr;
tail=tmp;
}否则{
tmp->prev=尾部;
tail->next=tmp;
tmp->next=nullptr;
tail=tmp;
}
}
空插入下一个(T项){
Node*tmp=新节点();
tmp->next=nullptr;
tmp->data=物料;
tmp->prev=nullptr;
节点*iter=头部;
while(iter!=nullptr){
if(iter->next==nullptr){
iter->next=tmp;
tmp->prev=iter;
返回;
}
iter=iter->next;
}
}
//如果未找到,则返回0。始终添加检查
//在访问tmp->数据之前,为0
节点*查找(T项){
节点*tmp=头部;
while(tmp&&tmp->data!=项目){
tmp=tmp->next;
}
返回tmp;
}
布尔删除节点(节点*节点){
if(node==nullptr){
返回false;
}else if(节点==头部){
head=节点->下一步;
删除节点;
返回true;
}否则{
节点*tmp=头部;
while(tmp){
if(tmp->next==节点){
tmp->next=节点->下一步;
删除节点;
返回true;
}
tmp=tmp->next;
}
}
返回false;
}
作废打印(){
节点*tmp;
tmp=头部;
while(tmp!=nullptr){
下一步是收集数据;
}

cout在函数insertHead中,我将
head->data=item
更改为下一行

head->data.index = item.index; head->data.data = item.data;
然后它打印了32-A。所以你有一个=运算符重载的问题。然后我改变了你的重载,如下所示:

void操作符=(const Dictionary&obj){index=obj.index;data=obj.data;}

您的字典上的=操作现在运行正常

如果要使用注释中所述的原始签名,则应将以前的重载函数更新为:

 Dictionary& operator=(Dictionary const & obj){
    this->index = obj.index;
    this->data = obj.data;
    return *this;
}
我想通过自我分配检查来改进答案。重载=运算符时,内部结构如下所示:

  • 取消分配此服务器所保留的内存
  • 为给定的参数对象分配内存
  • 复制值并返回
  • 因此,如果您尝试以下方法:

    Dictionary dummyDict;
    dummyDict=dummyDict;
    
    您的程序将失败。因此最终答案将是:

    Dictionary& operator=(Dictionary const & obj){
        if(this == &obj){
            return *this;
        }
        this->index = obj.index;
        this->data = obj.data;
        return *this;
    }
    

    在函数insertHead中,我将
    head->data=item
    更改为下一行

    head->data.index = item.index; head->data.data = item.data;
    
    然后它打印了32-A。所以你有一个=运算符重载的问题。然后我改变了你的重载,如下所示:

    void操作符=(const Dictionary&obj){index=obj.index;data=obj.data;}

    您的字典上的=操作现在运行正常

    如果要使用注释中所述的原始签名,则应将以前的重载函数更新为:

     Dictionary& operator=(Dictionary const & obj){
        this->index = obj.index;
        this->data = obj.data;
        return *this;
    }
    
    我想通过自我分配检查来改进答案。重载=运算符时,内部结构如下所示:

  • 取消分配此服务器所保留的内存
  • 为给定的参数对象分配内存
  • 复制值并返回
  • 因此,如果您尝试以下方法:

    Dictionary dummyDict;
    dummyDict=dummyDict;
    
    您的程序将失败。因此最终答案将是:

    Dictionary& operator=(Dictionary const & obj){
        if(this == &obj){
            return *this;
        }
        this->index = obj.index;
        this->data = obj.data;
        return *this;
    }
    

    在valgrind下运行您的代码,它将解释segfault发生的位置和原因。在valgrind下运行您的代码,它将解释segfault发生的位置和原因。这是正确的,运算符=重载从不修改此
    ,并按值返回一个新的Dictionary对象。实际上,运算符=不做任何操作,并且使对象未初始化。但是e不应修改insertHead()因为它是一个模板。所以我必须以某种方式修改运算符=。你的答案返回void。难道我们不应该返回一个Dictionary对象吗?据我所知,在initHead中,你试图访问NULL的数据属性,你必须先初始化head节点,例如使用new。我之前说过你试图访问数据属性,但你是不只是尝试访问数据属性,还要访问next和prev。正如我前面提到的,在执行此操作之前,您必须首先初始化head节点,因为它为NULL。我想应该是使用自分配而不是自分配