C++中单链接列表赋值运算符重载

Ant*_*sis 1 c++ singly-linked-list

我有以下单链表实现.

template <typename T> struct node{
    node(T data):data(data),next(nullptr){}
    T data;
    node<T> * next;
};

template< typename T> class slist{
    node<T>* head;
    int size;
public:
    slist(node<T>* head):head(head), size(0){}

    slist(const slist<T>& rhs){

        node<T>* temp = rhs.getHead();
        node<T>* p = new node<T>(temp->data);
        head = p;
        node<T>* current = p;
        while(temp != nullptr){
            current = current->next;
            current->data = temp->data;
        }

    }
    ~slist(){
        if(head == nullptr) return;

        while(head != nullptr){
            node<T>* current = head;
            head = head->next;
            delete(current);
        }
    }
    slist& operator= (const slist& rhs){


    }
    node<T>* getHead()const {
        return head;
    }


    void insertFront(T item){
        node<T>* p = new node<T>(item);
        if(head == nullptr){
            p = head;
            size++;
            return;
        }
        p->next = head;
        head = p;
        size++;
    }

    void insertBack(T item){
        node<T>* p = new node<T>(item);
        node<T>* current = head;
        while(current->next != nullptr){
            current = current->next;
        }
        current->next = p;
        size++;
    }

    void remove(T item){
        bool check = false;

        node<T>* current = head;
        try {
            while(current != nullptr){
                if(current->data == item) check = true;
                current = current->next;
            }
            if(!check){
                throw std::runtime_error("Item not in list");

            }
        }catch(std::runtime_error& e){
            std::cout<<e.what()<<std::endl;
            exit(-1);
        }

        current = head;
        while(current != nullptr){
           if(current->next->data == item){
               node<T>* temp = current->next;
               current->next = current->next->next;
               delete(temp);
               break;
           }
            current = current->next;
        }
        size--;

    }
    int getSize () const {
        return size;
    }

    void printList(){
        node<T>* current = head;
        while(current != nullptr){
            if(current->next != nullptr){
                std::cout<<current->data<<"->";
            }else{
                std::cout<<current->data<<std::endl;
            }
            current = current->next;
        }
    }


};
Run Code Online (Sandbox Code Playgroud)

根据类的当前实现和复制构造函数,有人可以帮助赋值运算符重载.另外,我对复制构造函数和赋值重载有点困惑.我的理解是复制构造函数创建一个新列表,它与旧列表中的旧列表具有相同的值.这个所有节点的下一个地址将是不同的,但值是相同的,因为它是一个深拷贝.我的理解是正确的,然后是分配超载的作用吗?

Die*_*ühl 5

如果您已经有了复制构造函数和析构函数,swap()那么还要根据这三个来实现并实现您的复制赋值运算符,例如:

template <typename T>
slist<T>& slist<T>::operator= (slist<T> other) {
    this->swap(other);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

请注意,参数很容易被复制:与复制构造函数不同,复制赋值可以通过值获取其参数.

关于语义:

  • 复制构造函数创建一个与原始对象具有相同值的新对象,例如:

    slist<int> sl1;
    // insert elements into sl1
    slist<int> sl2(sl1); // uses the copy constructor
    
    Run Code Online (Sandbox Code Playgroud)
  • 复制赋值将现有对象的值替换为指定值的值,例如

    slist<int> sl1;
    slist<int> sl2;
    // possibly modify both sl1 and sl2
    sl2 = sl1; // uses the copy assignment operator
    
    Run Code Online (Sandbox Code Playgroud)