need help deriving from the std::list class

J

JustSomeGuy

I need to write an new class derived from the list class.
This class stores data in the list to the disk if an object
that is added to the list is over 1K in size.

What methods of the std stl list class must Ioverride in order for this
to work?
 
V

Victor Bazarov

JustSomeGuy said:
I need to write an new class derived from the list class.
This class stores data in the list to the disk if an object
that is added to the list is over 1K in size.

What methods of the std stl list class must Ioverride in order for this
to work?

You will not be able to _override_ any members because none of them
are virtual.

I recommend private inheritance (or what in OO world is known as
"implement in terms of" relationship). You will need to implement
the interface you need and if the objects are smaller than 1K, let
the underlying std::list handle them in memory, and if they are
greater, do something else (like retrieve them from disk based on
the information your underlying list keeps).

Victor
 
J

JustSomeGuy

Victor said:
You will not be able to _override_ any members because none of them
are virtual.

I recommend private inheritance (or what in OO world is known as
"implement in terms of" relationship). You will need to implement
the interface you need and if the objects are smaller than 1K, let
the underlying std::list handle them in memory, and if they are
greater, do something else (like retrieve them from disk based on
the information your underlying list keeps).

Victor

I tried this and it works...

class mylist : public list<int>
{
public:
void push_back(const int & x)
{
list<int>::push_back(x);
}
};

Compiles and works .... Has this not overriden push_back?
What other methods need to be overridden?
 
V

Victor Bazarov

JustSomeGuy said:
Victor Bazarov wrote:




I tried this and it works...

class mylist : public list<int>
{
public:
void push_back(const int & x)
{
list<int>::push_back(x);
}

You don't need this for your 'mylist' to function as a list of
ints. Since you inherit publicly, whenever you call 'push_back'
for your 'mylist' object, the std::list::push_back is going to
be called.
};

Compiles and works .... Has this not overriden push_back?

No, it has not overridden push_back. Only virtual functions can be
overridden. What your 'push_back' has done is called _hiding_ of
the original push_back function.
What other methods need to be overridden?

I guess you don't understand the difference in terms. "Override"
only applies to virtual functions. Since 'std::list' has none,
you _cannot_ override anything. No matter what you try, it is not
going to be "overriding".

Now, if you don't care for your special list to work polymorphically,
you shouldn't worry about your inability to override anything. Just
write the functions you need and then let the std::list do the rest.

Keep in mind that your list is not going to work polymorphically.
If by some chance you write

class MyOwnListOfBigScaryObjects :
public std::list<MyBigScaryObject> {
...
};

void foo(std::list<MyBigScaryObject>& mylist) {
mylist.push_back(someScaryObject);
}

that even if you define your own push_back member in your class,
it will NOT be called. I am not trying to talk you out of deriving
from 'std::list', just warning you of potential pitfalls.

Victor
 
J

JustSomeGuy

Victor said:
You don't need this for your 'mylist' to function as a list of
ints. Since you inherit publicly, whenever you call 'push_back'
for your 'mylist' object, the std::list::push_back is going to
be called.


No, it has not overridden push_back. Only virtual functions can be
overridden. What your 'push_back' has done is called _hiding_ of
the original push_back function.

Ok perhaps this is just a question of symantics then overridding vs hinding...


I guess you don't understand the difference in terms. "Override"
only applies to virtual functions. Since 'std::list' has none,
you _cannot_ override anything. No matter what you try, it is not
going to be "overriding".

Now, if you don't care for your special list to work polymorphically,
you shouldn't worry about your inability to override anything. Just
write the functions you need and then let the std::list do the rest.

Ok what functions do I 'need' to write? I think that is the original
question.
Yes they are very big objects on average the list grows to 40 Mega-Bytes.
Keep in mind that your list is not going to work polymorphically.
If by some chance you write

Are you saying that no one will be able to treat my class as a stl sdt::list?

class MyOwnListOfBigScaryObjects :
public std::list<MyBigScaryObject> {
...
};

void foo(std::list<MyBigScaryObject>& mylist) {
mylist.push_back(someScaryObject);
}

that even if you define your own push_back member in your class,
it will NOT be called. I am not trying to talk you out of deriving
from 'std::list', just warning you of potential pitfalls.

I apprieate the warning... :)
 
V

Victor Bazarov

JustSomeGuy said:
Victor Bazarov wrote:




Ok perhaps this is just a question of symantics then overridding vs hinding...

Semantics is integral part of any language. English or C++. It is
important to understand the difference even if only to ignore it.
Ok what functions do I 'need' to write?

How should *I* know? You're going to be using the class, not I.
I think that is the original
question.

But who except you can answer this?

If you want your class to be used by standard algorithms for searching,
sorting, etc., you need to provide iterators to the contents of your
collection. I strongly recommend a good book on the standard library
(Nicolai Josuttis wrote the best so far). The margins of this posting
are not wide enough to accommodate a decent explanation on how to write
your own library-compliant container.
Yes they are very big objects on average the list grows to 40 Mega-Bytes.

I believe you.
Are you saying that no one will be able to treat my class as a stl sdt::list?

What do you mean by "treat" your class as std::list? You cannot pass
a pointer or a reference to your class to another function that expects
a pointer or a reference to std::list, and have that other function call
member functions of _your_ class. If the functions are not virtual (and
they are not in std::list), they are not going to be resolved to your
"variations".

OTOH, if the other function is expecting _your_ list (either as a pointer
or as a reference, don't try passing it by value), then everything should
be fine.

In general you should remember that if you want the rest of the world to
be able to think that your class is just like std::list, your class must
have "is-a" relationship with std::list. However, if you want some of
std::list behaviour substituted for your own in certain conditions, you
need polymorphism, and none of standard containers provide that. That's
why I said that you'd be better off reimplementing everything you need
while deriving from std::list privately. At least then you will be able
to prevent people from passing your wonderful class into functions that
expect std::list (private inheritance disables implicit conversion to
base).
I apprieate the warning... :)

You're welcome.
 
P

Prateek R Karandikar

JustSomeGuy said:
I need to write an new class derived from the list class.
This class stores data in the list to the disk if an object
that is added to the list is over 1K in size.

What methods of the std stl list class must Ioverride in order for this
to work?

std::list is not a class, it is a template. When you instantiate it by
providing arguments to the template parameters, you get a class.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
T

tom_usenet

I need to write an new class derived from the list class.
This class stores data in the list to the disk if an object
that is added to the list is over 1K in size.

What methods of the std stl list class must Ioverride in order for this
to work?

I would suggest not inheriting from std::list at all, but providing
your own limited list interface, where you can intercept the "size" of
intercepted objects more easily. With std::list, there are many ways
of adding elements to the list, and many of them can't be intercepted.
e.g.

*mylist.begin() = myenormousobject;
//your list type never gets to intercept that
or:
std::list& l = mylist;
l.push_back(myenormousobject);
//your list type never gets to intercept that

Instead, provide a limited interface that gives you the control you
need:

class MyList
{
std::list<MyObject> m_list; //or use private inheritence
public:
const_iterator begin() const;
const_iterator end() const;
//don't provide non-const iterators.

void push_back(MyObject const& object);

//add a few more functions, but how many do you need?
};

Tom
 
M

Michiel Salters

JustSomeGuy said:
I need to write an new class derived from the list class.
This class stores data in the list to the disk if an object
that is added to the list is over 1K in size.

What methods of the std stl list class must Ioverride in order for this
to work?

Actually, you probably shouldn't try to override list. Instead, you should
proxy the class you put in.

E.g. instead of
std::list<MyClass> list;
you write
std::list<MyClassProxy> list;

Example definitions for MyClass and MyClassProxy:

class MyClass {
std::string sometimes_big;
public:
std::string get() const;
}


class MyClassProxy {
bool in_file;
std::string filename_or_smallstring;
public:
MyClassProxy( MyClass const& mc ) {
filename_or_smallstring = mc.get();
in_file = false;
if( filename_or_smallstring.size() >= 1024 )
{
filename_or_smallstring = save_to_newfile(filename_or_smallstring);
in_file = true;
}
}
std::string get() const {
if(infile)
return read_from_file(filename_or_smallstring);
else
return filename_or_smallstring;
}
operator MyClass() const { return MyClass(get()); }
private:
std::string save_to_newfile( std::string const& s ); // returns filename
std::string read_from_file ( std::string const& filename );
};
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top