A simple c++ question...

J

JustSomeGuy

I have a few classes...

class a : std::list<baseclass>
{
int keya;
};

class b : std::list<a>
{
int keyb;
};

class c : std::list<b>
{
int keyc;
};


I'm trying to figure out at each level the size of the lists...

so if I have:

int main(int argc, char *argv[])
{
c x;

cout << "The size of the c class list is " << x.size() << endl;
cout << "The size of the b class list is " << ???? << endl;
cout << "The size of the a class list is " << ???? <<< endl;
}
-------------------------------------------------------------------------

Thinking about it...
Using inheritance of std::list may not have been the best idea..
perhaps:

class a : std::list<baseclass>
{
int keya;
std::list<sometype> baseclasslist;
};

class b
{
int keyb;
std::list<a> alist;
};

class c
{
int keyc;
std::list<b> blist;
};

May have been a better implementation, but the question remains.
 
G

Gianni Mariani

JustSomeGuy said:
I have a few classes...

class a : std::list<baseclass>
{
int keya;
};

class b : std::list<a>
{
int keyb;
};

class c : std::list<b>
{
int keyc;
};


I'm trying to figure out at each level the size of the lists...

so if I have:

int main(int argc, char *argv[])
{
c x;

cout << "The size of the c class list is " << x.size() << endl;
cout << "The size of the b class list is " << ???? << endl;
cout << "The size of the a class list is " << ???? <<< endl;
}

There is not one list for b and a, there are multiple lists.

Are you sure you want lists of lists of lists ?

-------------------------------------------------------------------------

Thinking about it...
Using inheritance of std::list may not have been the best idea..
perhaps:

class a : std::list<baseclass>
{
int keya;
std::list<sometype> baseclasslist;
};

class b
{
int keyb;
std::list<a> alist;
};

class c
{
int keyc;
std::list<b> blist;
};

May have been a better implementation, but the question remains.

It depends.
 
D

Dave Townsend

Your problem was you were inherting privately, so you couldn't
access the size() function in the superclass of a, b,c etc. Here's
a working piece of code to 'splain it.

davet.

#include <iostream>
#include <list>
using namespace std;


class baseclass
{
public:

};
class A : public std::list<int>
{

int keya;
};

class B : public std::list<A>
{

int keyb;
};

class C : public std::list<B>
{

int keyc;
};



int main()
{
A a;
B b;
C c;

for (int k=0; k<10; k++)
{
for (int j=0; j<10 ; j++)
{
for (int i=0; i< 10; i++)
{

a.push_back(i);

}

b.push_back(a);
}

c.push_back(b);
}

cout << "The size of the a class list is " << a.size() << endl;

cout << "The size of the b class list is " << b.size() << endl;
cout << "The size of the c class list is " << c.size() << endl;

return 0;
}
 
D

David Hilsee

JustSomeGuy said:
I have a few classes...

class a : std::list<baseclass>
{
int keya;
};

class b : std::list<a>
{
int keyb;
};

class c : std::list<b>
{
int keyc;
};


I'm trying to figure out at each level the size of the lists...

so if I have:

int main(int argc, char *argv[])
{
c x;

cout << "The size of the c class list is " << x.size() << endl;
cout << "The size of the b class list is " << ???? << endl;
cout << "The size of the a class list is " << ???? <<< endl;
}

Each instance of c contains multiple instances (a std::list) of b, and each
instance of b contains multiple instances (another std::list) of a. Your
code implies that for each instance of c there can only be one instance of b
and only one instance of a, which is not the case.

To display the sizes of each std::list instantiated by the above code, you
would have to iterate over each list. Example:

c x;

std::cout << "The size of c class list is " << x.size() << std::endl;

for ( c::iterator cit = x.begin(); cit != x.end(); ++cit ) {
std::cout << "The size of b class list is " << cit->size() << std::endl;

for ( b::iterator bit = cit->begin(); bit != cit->end(); ++bit ) {
std::cout << "The size of a class list is " << bit->size() <<
std::endl;

for ( a::iterator ait = bit->begin(); ait != bit->end(); ++ait ) {
std::cout << "The size of baseclass class list is " <<
ait->size() << std::endl;
}
}
}

Some indentation might make the output a little clearer.
Thinking about it...
Using inheritance of std::list may not have been the best idea..


Many people frown upon inheriting from the standard containers because they
were not designed for inheritance (no virtual destructor, no virtual
functions, no protected members). I happen to be one of those people.
Composition would probably be better.
 
J

JustSomeGuy

using namespace std;

class a : public list<baseclass>
{
int keya;
};

class b : public list<a>
{
int keyb;
};

class c : public list<b>
{
int keyc;
};

void c::cleanItUp(c & x)
{
cout << "The size of c class list is " << x.size() << endl;

for ( c::iterator cit = x.begin(); cit != x.end(); ++cit )
{
cout << "The size of b class list is " << cit->size() << endl;

for ( b::iterator bit = cit->begin(); bit != cit->end(); ++bit )
{
cout << "The size of a class list is " << bit->size() << endl;

for ( a::iterator ait = bit->begin(); ait != bit->end(); ++ait )
{
cout << "The size of baseclass class list is " <<
ait->size() << endl;
}
}
}
}

At some point one instance of the baseclass is added to the list...
However for this to occure then one instance of a and one instance of b must
also exist.
This is done by the c::add(baseclass & x) method.

My question is... if that instance is removed then the parents need to be
removed as well.
So how do you check for this? ie a parent without children should remove
itself?
 
D

David Hilsee

JustSomeGuy said:
using namespace std;

class a : public list<baseclass>
{
int keya;
};

class b : public list<a>
{
int keyb;
};

class c : public list<b>
{
int keyc;
};

void c::cleanItUp(c & x)
{
cout << "The size of c class list is " << x.size() << endl;

for ( c::iterator cit = x.begin(); cit != x.end(); ++cit )
{
cout << "The size of b class list is " << cit->size() << endl;

for ( b::iterator bit = cit->begin(); bit != cit->end(); ++bit )
{
cout << "The size of a class list is " << bit->size() << endl;

for ( a::iterator ait = bit->begin(); ait != bit->end(); ++ait )
{
cout << "The size of baseclass class list is " <<
ait->size() << endl;
}
}
}
}

At some point one instance of the baseclass is added to the list...
However for this to occure then one instance of a and one instance of b must
also exist.
This is done by the c::add(baseclass & x) method.

My question is... if that instance is removed then the parents need to be
removed as well.
So how do you check for this? ie a parent without children should remove
itself?

The code you have provided is incomplete, but I'll tell you what I can.
Given the current implementation of the c class, it is impossible for it to
know when an instance of b, a, or baseclass has been added or removed from
its ancestor. Some other code could call std::list::push_back(),
std::list::erase(), std::list::clear(), etc, and the c class would have its
members modified without its knowledge or consent. The standard containers
do not provide any way for derived clases to be notified of modifications.
If you wish to control access to the std::list members of c, b, and a, then
you may want to consider making those std::lists private members of the
appropriate class and only exposing a very limited interface to the users of
the c class. That way, it may be easier to check for parents without
children, as well as guarantee other conditions that cannot be guaranteed by
the current implementation. In that scenario, it would be easy for a member
function c::add(baseclass & x), could have a member function
c::remove(<something>) to "undo" that operation. That is just a guess. I'd
have to know more about what you are doing to give you a complete answer.
 
J

JustSomeGuy

David Hilsee said:
The code you have provided is incomplete, but I'll tell you what I can.
Given the current implementation of the c class, it is impossible for it to
know when an instance of b, a, or baseclass has been added or removed from
its ancestor. Some other code could call std::list::push_back(),
std::list::erase(), std::list::clear(), etc, and the c class would have its
members modified without its knowledge or consent. The standard containers
do not provide any way for derived clases to be notified of modifications.
If you wish to control access to the std::list members of c, b, and a, then
you may want to consider making those std::lists private members of the
appropriate class and only exposing a very limited interface to the users of
the c class. That way, it may be easier to check for parents without
children, as well as guarantee other conditions that cannot be guaranteed by
the current implementation. In that scenario, it would be easy for a member
function c::add(baseclass & x), could have a member function
c::remove(<something>) to "undo" that operation. That is just a guess. I'd
have to know more about what you are doing to give you a complete answer.

I guess one way of looking at it would be to treat it like a directory
structure.

If a directory exists but has no files then that directory should be
deleted.

If a directory exists with no subdirectories or files then it too should be
deleted.

Does that explain it a bit better?

TIA
B.
 
D

David Hilsee

JustSomeGuy said:
I guess one way of looking at it would be to treat it like a directory
structure.

If a directory exists but has no files then that directory should be
deleted.

If a directory exists with no subdirectories or files then it too should be
deleted.

Does that explain it a bit better?

A little. My recommendation for making the containers private sounds right.
I don't really want to write the code out, but the approach is simple: write
classes (or possibly just one class) that contain private list(s) (or
whatever container), and then write public member functions that will add
and remove elements from those lists. The member functions can then ensure
that empty "directories" are removed.
 
R

Richard Herring

JustSomeGuy said:
I guess one way of looking at it would be to treat it like a directory
structure.

If a directory exists but has no files then that directory should be
deleted.

If a directory exists with no subdirectories or files then it too should be
deleted.
I'm glad you're not running any system I have to use. The mere existence
of a directory may convey important information, regardless of whether
there's anything in it.
 
J

JustSomeGuy

Richard Herring said:
I'm glad you're not running any system I have to use. The mere existence
of a directory may convey important information, regardless of whether
there's anything in it.

This is just an example... If you read the original posting you will see
that this is a hypothetical example.


 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top