"berkay" <be**********@gmail.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...
| //although i have friendship it give such an error but why?
| //error C2065: 'mystr' : undeclared identifier
| class CdBox
| {
| public:
| char *pronames[40] ;
| int CdNo;
|
| CdBox *next;
| vector<string> mystr;
|
| CdBox():mystr(1)
| {
| next=NULL;
| }
|
| friend class List;
| void display();
| };
Doesn't makes sense to me that a CDBox should need to know anything
about the container its in. Neither does the List need to know which
CDBox is adjacent to which. If you really need List to encapsulate its
internals as well as have direct access to the CDBox's structure,
then...
#include <iostream>
#include <ostream>
#include <string>
#include <list>
#include <vector>
class List
{
struct CDBox
{
int n;
std::string name;
CDBox(int i, std::string s) : n(i), name(s) { }
CDBox(const CDBox& copy);
{
n = copy.n;
name = copy.name;
}
~CDBox() { }
// missing assignment operator
}; // CDBox
std::list< CDBox > boxes;
public:
List() : boxes() { }
List(const List& copy); // disabled for now
~List() { }
/* member functions */
void push_back( const int n, const std::string& s )
{
boxes.push_back(CDBox(n, s));
}
void display() const
{
std::cout << "This List has " << boxes.size() << " elements:\n";
typedef std::list< CDBox >::const_iterator CD_Iter;
CD_Iter it = boxes.begin();
for (it; it != boxes.end(); ++it)
{
std::cout << "CDBox number " << (*it).n << "\t";
std::cout << "name: " << (*it).name << "\n";
}
}
}; // List
int main()
{
List list;
list.push_back(0, "box1");
list.push_back(1, "box2");
list.display();
return 0;
}
/*
This List has 2 elements:
CDBox number 0 name: box1
CDBox number 1 name: box2
*/
|
| class List
| {
| private:
| CdBox *tail,*head,*TOP;
| public:
| List()
| {
| TOP=new CdBox;
| head=tail=TOP;
| TOP->next=NULL;
| }
| friend class CdBox;
| void append(CdBox *);
| void load();
|
| };
|
If you prefer not to rely on the standard list but wish to construct
your own then i'ld suggest starting off small and simple. CDBox only
holds a single integer and a pointer to next.
Only an instance of the List class needs to know about CDBox's
compostion. So again CDBox is an embedded class of the List class. CDBox
doesn't care nor need to know anything about List. Conversely, List does
not need to know which CDBox is next, it only tracks the head, tail and
maybe its own size. The member function add(..) can only push_back a new
CDBox allocation. Unload() deallocates all. As is, you can't copy this
List.
You can't create a container with responsabilities not clearly defined
between the element's responsibility and the container's responsability.
Every time you add a new feature, you have to carefully breakpoint
through the code to observe that all those pointers get set
appropriately. The more pointers you provide, the higher the cost when
adding features.
#include <iostream>
class List
{
struct CDBox
{
const int number;
CDBox *next;
CDBox(int i, CDBox *p) : number(i), next(p) { }
CDBox(const CDBox& copy); // disabled
~CDBox() { }
} *head, *tail;
int size;
public:
List() : head(0), tail(0), size(0) { }
List(const List& copy); // disabled for now
~List() { }
/* member functions */
void add(const int& n)
{
std::cout << "add(" << n << ")\n";
if(tail != 0)
{
CDBox* box = new CDBox(n, 0);
tail->next = box;
tail = box;
}
else
{
tail = head = new CDBox(n, 0);
}
++size;
}
void unload()
{
std::cout << "\nunload()\n";
if(tail != 0)
{
CDBox* box = head;
do
{
CDBox* temp = box;
box = temp->next;
delete temp;
--size;
} while(box != 0); // or while(size > 0);
head = tail = 0;
}
}
void display() const
{
std::cout << "\n_______________________\t";
std::cout << "display() list: # of elements: " << size << "\n";
std::cout << "head: " << head << "\n";
std::cout << "tail: " << tail << "\n";
if(size > 0)
{
CDBox* temp = head;
do
{
std::cout << "element:" << temp << "\t";
std::cout << "number = " << temp->number;
std::cout << ", next = " << temp->next << "\n";
temp = temp->next;
} while(temp != 0);
}
else
{
std::cout << "List is empty\n";
}
std::cout << "_______________________\n";
}
}; // List
int main()
{
List list;
list.add(0);
list.add(1);
list.add(2);
list.display();
list.unload();
list.display();
return 0;
}
/*
add(0)
add(1)
add(2)
_______________________ display() list: # of elements: 3
head: 007E0700
tail: 007E0D50
element:007E0700 n = 0, next = 007E0E60
element:007E0E60 n = 1, next = 007E0D50
element:007E0D50 n = 2, next = 00000000
_______________________
unload()
_______________________ display() list: # of elements: 0
head: 00000000
tail: 00000000
List is empty
_______________________
*/
Not a trivial task, and i'm sure that if you look hard enough, you'll
find a bug or two.
Probably a worthwhile suggestion considering all the work involved is to
template the List class so that it can store *any* type of element.
class CDBox
{
...
};
template< class Node >
class List
{
Node* head;
Node* tail;
int size;
public:
List() : head(0), tail(0), size(0) { }
~List() { }
/*member functions*/
void add(const Node& node)
{
...
}
void unload()
{
...
}
};
int main()
{
List< CDBox > cd_list;
cd_list.add(CDBox(...));
cd_list.unload();
List< double > d_list;
d_list.add(1.0);
d_list.unload();
return 0;
}