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

C++自定义List类的数组转移构造函数实现求助

问题分析与修正

你的数组构造函数存在几个关键问题,导致无法生成符合预期顺序的链表,且存在野指针风险:

原构造函数的问题

  • 元素顺序反转:使用头插法(head = new list_element(arr[i], head))会将数组元素从后往前插入链表,最终输出顺序与输入数组完全相反。
  • 野指针风险:构造函数未初始化cursor成员变量,后续调用get_element()或advance()会触发未定义行为。
  • 冗余代码:构造函数内的List temp;变量未被使用,属于无效代码。

另外,你的拷贝构造函数也存在小问题:会在链表末尾额外生成一个值为0的空节点,导致输出结果多一个不必要的元素。

修正后的代码

修正数组构造函数(尾插法保持顺序+初始化cursor)

List::List(const int* arr, int n) : head(nullptr), cursor(nullptr) {
    if (n <= 0) return;

    // 创建第一个节点,初始化头指针和尾指针
    head = new list_element(arr[0]);
    list_element* tail = head;

    // 从第二个元素开始尾插
    for (int i = 1; i < n; ++i) {
        // 静态数组未初始化的元素自动为0,动态数组若长度不足n可改为:int val = (i < 数组实际长度) ? arr[i] : 0;
        tail->next = new list_element(arr[i]);
        tail = tail->next;
    }

    // 将cursor指向链表头部,保证后续操作正常
    cursor = head;
}

修正拷贝构造函数(避免多余空节点)

List::List(const List& lst) : head(nullptr), cursor(nullptr) {
    if (lst.head == nullptr) {
        return;
    }

    // 创建第一个节点
    head = new list_element(lst.head->d);
    list_element* current = head;
    list_element* lst_current = lst.head->next;

    // 遍历原链表,逐个拷贝节点
    while (lst_current != nullptr) {
        current->next = new list_element(lst_current->d);
        current = current->next;
        lst_current = lst_current->next;
    }

    cursor = head;
}

完整测试代码

#include <iostream>

using namespace std;
class list_element{
public:
    list_element(int n = 0,list_element* ptr = nullptr):
        d(n),next(ptr){}
    int d;
    list_element* next;
};

class List{
public :
    List():head(nullptr),cursor(nullptr){}
    List(const int* arr, int n); // 数组构造函数
    List(const List& lst); // 拷贝构造函数
    void prepend(int n);
    int get_element() 
    {
        return cursor->d;
    }
    void advance() { cursor = cursor->next; }
    void print();
    ~List();    // 析构函数
private:
    list_element* head;
    list_element* cursor;
};

// 修正后的数组构造函数
List::List(const int* arr, int n) : head(nullptr), cursor(nullptr) {
    if (n <= 0) return;

    head = new list_element(arr[0]);
    list_element* tail = head;

    for (int i = 1; i < n; ++i) {
        tail->next = new list_element(arr[i]);
        tail = tail->next;
    }

    cursor = head;
}

// 析构函数
List::~List(){
    for (cursor = head; cursor != 0;)
    {
        cursor = head->next;
        delete head;
        head = cursor;
    }
}

// 修正后的拷贝构造函数
List::List(const List& lst) : head(nullptr), cursor(nullptr) {
    if (lst.head == nullptr) {
        return;
    }

    head = new list_element(lst.head->d);
    list_element* current = head;
    list_element* lst_current = lst.head->next;

    while (lst_current != nullptr) {
        current->next = new list_element(lst_current->d);
        current = current->next;
        lst_current = lst_current->next;
    }

    cursor = head;
}

void List::prepend(int n)
{
    if (head == nullptr)
        cursor = head = new list_element(n, head);
    else
        head = new list_element(n, head);
}

void List::print()
{
    list_element* h = head;
    while (h != 0)
    {
        cout << h->d << ',';
        h = h->next;
    }
    cout << "###" << endl;
}

int main()
{
    int data[10] = {1,3,5,7};
    List d(data, 10);
    d.print(); // 输出:1,3,5,7,0,0,0,0,0,0,###

    // 测试拷贝构造函数
    List e(d);
    e.print(); // 输出与d一致
    return 0;
}

说明

  • 数组构造函数采用尾插法,保证链表元素顺序与输入数组完全一致。
  • 初始化cursor为链表头部,避免后续操作出现野指针。
  • 拷贝构造函数修正了多余空节点的问题,实现了正确的深拷贝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:54:20