By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,978 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,978 IT Pros & Developers. It's quick & easy.

need help deriving from the std::list class

P: n/a
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?
Jul 22 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
JustSomeGuy wrote:
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
Jul 22 '05 #2

P: n/a
Victor Bazarov wrote:
JustSomeGuy wrote:
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


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?
Jul 22 '05 #3

P: n/a
JustSomeGuy wrote:
Victor Bazarov wrote:

JustSomeGuy wrote:
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

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
Jul 22 '05 #4

P: n/a
Victor Bazarov wrote:
JustSomeGuy wrote:
Victor Bazarov wrote:

JustSomeGuy wrote:

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

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.


Ok perhaps this is just a question of symantics then overridding vs hinding...
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.


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... :)

Victor


Jul 22 '05 #5

P: n/a
JustSomeGuy wrote:
Victor Bazarov wrote:

JustSomeGuy wrote:
Victor Bazarov wrote:

JustSomeGuy wrote:
>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
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.

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.
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.

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.
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?


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).
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... :)


You're welcome.
Jul 22 '05 #6

P: n/a
JustSomeGuy <No***@ucalgary.ca> wrote in message news:<40***************@ucalgary.ca>...
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
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Jul 22 '05 #7

P: n/a
On Mon, 07 Jun 2004 13:40:03 -0600, JustSomeGuy <No***@ucalgary.ca>
wrote:
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
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #8

P: n/a
JustSomeGuy <No***@ucalgary.ca> wrote in message news:<40***************@ucalgary.ca>...
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 );
};
Jul 22 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.