[TriLUG] c++ proper away do an assignment overload for a linked list.
Ralph Blach
chipperb at nc.rr.com
Thu Jan 28 14:30:11 EST 2010
To learn C++ an am trying to write a linked list, no hard, in c++,
However, creating an proper assignment overload, is very difficult.
Here is my code so far.
#include <iostream>
#include <cstdlib>
using namespace std;
class ll_node
{
public :
ll_node() {next = 0;prev = 0; }
ll_node(const string &val) {next = 0; prev=0; value=val;}
ll_node(ll_node * n_ll_node,const string &
val){next=n_ll_node;prev=0;value=val;}
int get_s() ;
void set_s( int x);
// work with the next porinters
void set_next( ll_node * lln_next) {next=lln_next;};
ll_node *get_next (void) const {return next;}
const ll_node *const get_next ( ll_node* lnode ) {return
lnode->get_next();}
// previous pointe
void set_prev( ll_node * lln_prev){prev=lln_prev;};
ll_node * get_prev( ) const {return
prev;};
const ll_node * const get_prev ( ll_node* lnode ) const
{return lnode->get_prev();}
//data operators
void set_value(const int & s){ value=s;}
string get_value () const {return value;}
void set_st(int i){s=i;}
int get_st(int i){return s;}
//
// private area for the linked list
private:
string value;
ll_node *next;
ll_node *prev;
static int s;
};
class ll_list
{
public:
void push_top(const string &i);
string pop_top(void);
void walk_top(void);
void walk_bottom(void);
const ll_node * get_first ( ) const {return first;}
const ll_node * get_last ( ) const {return last;}
void push_bottom(const string &value);
string pop_bottom(void);
//clear the list delete all values.
void clear(void);
//see if the list if empty, or how many elements are in the list
bool empty(void)const { if (llsize) return false; else return true; }
int length (void)const {return llsize;}
//find a value
ll_node * find_value(const string &val);
//constructors
ll_list () {first=0;last=0;next=0;llsize=0;}
//destructor
~ll_list() {clear ();};
static const int llempty=-1>>1; //the largest int is alwasy a
return code
// the assignemt overload
ll_list & operator=(const ll_list &rhs);
// the copy constructor
ll_list ( const ll_list & list );
//friend const ll_list operator +(const ll_lhs &lhs, const ll_node &rhs);
private:
int llsize;
ll_node * first;
ll_node * last;
ll_node * next;
};
#if 0
//copy constuctor.
ll_list::ll_list(const ll_list & list )
{
const ll_node * const lnode =list.get_last();
ll_node * tmp=lnode;
string s;
first=0;//one has to initialize all the values.
last=0; //of the new list
llsize=0;
while (tmp )
{
s=tmp->get_value();
push_top(s);
tmp=tmp->get_prev();
}
}
#endif
/******************************************************/
// = assignement overload.
ll_list& ll_list::operator=(const ll_list &rhs) //<-here is the problem.
I have to pass the rhs as a const &
{
// Only do assignment if RHS is a different object from this.
if (this != &rhs )
{
if (rhs.empty())
{
clear();
return *this;
}
string s;
const ll_node * const lnode =rhs.get_last(); //then recreate
a read only node. How do I create a read only or const node, that does not
//seem to mutate the right hand side, and does not have any back doors.
//ll_node * tmp=lnode;
// Deallocate, allocate new space, copy values...
//first delete all the nodes
clear();
//next set the top of the rhs
//next put all the nodes back on the new list.
while (lnode )
{
push_top(lnode->get_value());
//cout<<"in assingmet lnode="<<lnode<<endl;
lnode=lnode->get_prev(lnode);
}
}
return *this;
}
void ll_list::push_top(const string &value)
{
llsize++;
//ll_node *tmp;
first=new ll_node(first,value);
if (last == 0 ) //start of the list no nodes in list
{
last = first;
}
else //it is not the first link we need to update the previous nodee
{
ll_node * next;
next=first->get_next(); //so now we have the pointer to next,
//link in the list.
next->set_prev(first);
}
}
string ll_list::pop_top(void)
{
string value="";
ll_node * tmp=0;
if (first == 0 )
{
return "";
}
llsize--;
tmp=first;
if (first == last)
{
first=0;
last=0;
value=tmp->get_value();
}
else
{
first=first->get_next();
first->set_prev(0);
}
value=tmp->get_value();
delete tmp;
return value;
}
//clear the link list.
void ll_list::clear(void)
{
while ( first != 0 )
{
pop_top();
}
}
//
void ll_list::walk_top(void)
{
ll_node * nptr=first;
while ( nptr)
{
cout<<nptr->get_value()<<endl;
nptr=nptr->get_next();
}
}
void ll_list::walk_bottom(void)
{
ll_node * nptr=last;
while ( nptr)
{
cout<<nptr->get_value()<<endl;
nptr=nptr->get_prev();
}
}
ll_node * ll_list::find_value(const string & val)
{
ll_node * nptr=first;
while ( nptr)
{
if (val==nptr->get_value())
{
return nptr;
}
nptr=nptr->get_next();
}
return nptr;
}
void ll_list::push_bottom(const string &value)
{
ll_node *tmp;
llsize++;
tmp=new ll_node(value);
//now add the node to the bottome of thelist
if (last == 0 ) //start of the list no nodes in list
{
last=first=tmp;
tmp->set_prev(0);
tmp->set_next(0);
}
else //it is not the first link we need to update the previous nodee
{
last->set_next(tmp);
tmp->set_prev(last);
last=tmp;
}
}
string ll_list::pop_bottom(void)
{
string value="";
ll_node * tmp=0;
if (first == 0 )
{
cout<<"list is empty"<<endl;
return "";
}
llsize--;
tmp=last;
if (first == last)
{
first=0;
last=0;
value=tmp->get_value();
}
else
{
last=tmp->get_prev();
last->set_next(0);
}
value=tmp->get_value();
delete tmp;
return value;
}
void copy_test( ll_list my_list)
{
cout<<"in copy constructor test"<<endl;
my_list.walk_top();
}
int main ( int argc, char * argv[])
{
ll_list myll;
ll_node * lnode;
string temp;
myll.push_bottom("11");
myll.push_bottom("12");
myll.push_bottom("13");
myll.push_bottom("14");
cout<<"walk_top"<<endl;
myll.walk_top();
myll.pop_bottom();
{
cout <<"to destructor test"<<endl;
ll_list newll;
newll.push_top("aaa");
newll.push_top("bbb");
cout<<"newll walk top"<<endl<<endl;
newll.walk_top();
cout<<"myll walk top"<<endl<<endl;
myll.walk_top();
cout<<"to assingment\n\n"<<endl<<endl;
newll=myll;
cout<<"after assignemnt new walk top"<<endl<<endl;
newll.walk_top();
cout <<"to copy constructor"<< endl;
copy_test(newll);
}
return 0;
}
More information about the TriLUG
mailing list