bit*_*cle 1 c++ pointers linked-list dynamic-memory-allocation
大家好.我正在做一个涉及动态内存分配,指针,类和异常的链表练习.有人愿意批评它并告诉我我做错了什么以及我应该在风格和上面列出的那些主题方面做得更好吗?
/*
Linked List exercise
*/
#include <iostream>
#include <exception>
#include <string>
using namespace std;
class node{
public:
node * next;
int * data;
node(const int i){
data = new int;
*data = i;
}
node& operator=(node n){
*data = *(n.data);
}
~node(){
delete data;
}
};
class linkedList{
public:
node * head;
node * tail;
int nodeCount;
linkedList(){
head = NULL;
tail = NULL;
}
~linkedList(){
while (head){
node* t = head->next;
delete head;
if (t) head = t;
}
}
void add(node * n){
if (!head) {
head = n;
head->next = NULL;
tail = head;
nodeCount = 0;
}else {
node * t = head;
while (t->next) t = t->next;
t->next = n;
n->next = NULL;
nodeCount++;
}
}
node * operator[](const int &i){
if ((i >= 0) && (i < nodeCount)) throw new exception("ERROR: Invalid index on linked list.", -1);
node *t = head;
for (int x = i; x < nodeCount; x++) t = t->next;
return t;
}
void print(){
if (!head) return;
node * t = head;
string collection;
cout << "[";
int c = 0;
if (!t->next) cout << *(t->data);
else while (t->next){
cout << *(t->data);
c++;
if (t->next) t = t->next;
if (c < nodeCount) cout << ", ";
}
cout << "]" << endl;
}
};
int main (const int & argc, const char * argv[]){
try{
linkedList * myList = new linkedList;
for (int x = 0; x < 10; x++) myList->add(new node(x));
myList->print();
}catch(exception &ex){
cout << ex.what() << endl;
return -1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
数据不需要成为指针.
使用ctor-initializer列表,它更适合const正确性和异常安全性.你的构造函数都不需要在体内有任何代码.
您的linkedList构造函数未初始化nodeCount.
您没有使用列表的尾部指针.它可以节省您在非空的添加情况下扫描整个列表 - 如果您保持最新.
索引(operator [])在链表上是一种不寻常的支持.OTOH你还没有删除功能.
operator []不应该通过引用获取其参数.只有大型结构需要通过const引用传递,像int这样的小类型应该只是通过值传递.
现在,如果添加失败,指向新node()的指针会泄漏.(但我实际上并没有看到添加失败的方法,除非列表链接被破坏.)
您应该在节点上定义私有拷贝构造函数以防止数据双重释放.每次定义operator =和析构函数时,您还应该定义或删除复制构造函数(三个规则).您还应该在linkedList上定义私有拷贝构造函数和赋值运算符以防止双重释放.
不使用print函数中的变量字符串集合.print()中的变量t应该是指向const的指针.print本身应该是const成员函数.