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
相关产品推荐
相关产品推荐

