 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Patrick Guest
|
Posted: Mon Feb 23, 2004 7:46 pm Post subject: STL Vectors & Memory |
|
|
In class *ClassA* below I have an STL Vector *vec* as a member
variable of the class.
Do I have to create a destructer, and somehow deallocate the memory
from *vec*, or is this handled automatically?
Also I want to allow a client of *ClassA* to be able to view the
elements of the vector.
Returning a reference to *vec* would be bad OO programming as i would
be returning a reference to a private member of the class.
I was thinking of using a method that would return an iterator over
the Vector i.e.
vector<int>::const_iterator ClassA::getIterator()
{ return vec.begin();
}
However i realised then that STL iterators dont have a reference to
the last element in the container, so this isnt viable. Also this is
pretty much the bad OO programming in the sense that while its a const
iterator and the Vector itself cant be modified, the elements of the
vector can be modified, i.e. once again allowing a client to modify
private data of the class.
Is there a design pattern or some construct of allowing the client to
view elements of the vector in a "read-only" fashion, while not
violating OO principles?...other than copying the entire vector
any help appreciated
pat
------------------- ClassA.h -----------------------------
#ifndef CLASSA_H
#define CLASSA_H
#include <vector>
class ClassA
{ public:
ClassA();
void addElement(int element);
private:
vector<int> vec;
};
#endif
------------------ ClassA.cpp ----------------------------
#include <vector>
using namespace std;
#include "ClassA.h"
ClassA::ClassA(){}
void ClassA::addElement(int element)
{ vec.push_back(element);
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Vecerina Guest
|
Posted: Tue Feb 24, 2004 3:31 am Post subject: Re: STL Vectors & Memory |
|
|
"Patrick" <googleaddress (AT) yahoo (DOT) co.uk> wrote
| Quote: | In class *ClassA* below I have an STL Vector *vec* as a member
variable of the class.
Do I have to create a destructer, and somehow deallocate the memory
from *vec*, or is this handled automatically?
Also I want to allow a client of *ClassA* to be able to view the
elements of the vector.
Returning a reference to *vec* would be bad OO programming as i would
be returning a reference to a private member of the class.
I was thinking of using a method that would return an iterator over
the Vector i.e.
Something you can do along this line is provide a const iterator to |
both the begin() and the end() of the vector.
But I usually find it easier and simpler to provide an accessor
to the const member:
class ClassA {
public:
//...
typedef std::vector<Item> ItemsT;
ItemsT const& items() const { return items_; }
//...
private:
ItemsT items_;
};
Returning a const-reference should ensure that the collection
cannot be modified, and that the invariants of ClassA are preserved.
Regarding encapsulation, providing a typedef for the type of the
collection is what really matters. Returning iterators instead of
the collection itself hardly improves encapsulation (if at all).
| Quote: | However i realised then that STL iterators dont have a reference to
the last element in the container, so this isnt viable. Also this is
pretty much the bad OO programming in the sense that while its a const
iterator and the Vector itself cant be modified, the elements of the
vector can be modified, i.e. once again allowing a client to modify
private data of the class.
Is there a design pattern or some construct of allowing the client to
view elements of the vector in a "read-only" fashion, while not
violating OO principles?...other than copying the entire vector
|
Using generic programming, a possible solution is to add
a member function such as:
template<class Fun>
Fun applyToEach( Fun f )
{ return std::for_each( items_.begin(), items.end(), f ); }
This is very similar to a Visitor pattern, but without run-time
polymorphism.
And it would also be possible to implement a classic OO-style Enumerator
(which is what I would call an Iterator that has a reference to
the last element of its collection).
There are many different options actually, and the best choice
really depends on details of the design...
Regards,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Robert R. Guest
|
Posted: Tue Feb 24, 2004 1:36 pm Post subject: Re: STL Vectors & Memory |
|
|
Patrick <googleaddress (AT) yahoo (DOT) co.uk> wrote
| Quote: | In class *ClassA* below I have an STL Vector *vec* as a member
variable of the class.
Do I have to create a destructer, and somehow deallocate the memory
from *vec*, or is this handled automatically?
|
This is handled automatically.
| Quote: | Also I want to allow a client of *ClassA* to be able to view the
elements of the vector.
Returning a reference to *vec* would be bad OO programming as i would
be returning a reference to a private member of the class.
I was thinking of using a method that would return an iterator over
the Vector i.e.
vector<int>::const_iterator ClassA::getIterator()
{ return vec.begin();
}
However i realised then that STL iterators dont have a reference to
the last element in the container, so this isnt viable. Also this is
pretty much the bad OO programming in the sense that while its a const
iterator and the Vector itself cant be modified, the elements of the
vector can be modified, i.e. once again allowing a client to modify
private data of the class.
any help appreciated
pat
|
It is impossible to modify elements of a vector with const_iterator,
so using const_iterators for readonly wiev of elements is a good idea.
However you need to return a pair of iterators,
or use two member functions.
Look at the example:
#include <vector>
#include <algorithm>
class ClassA
{
public:
// the typedef allows for easy change of a container
// for example to std::deque<int>
typedef std::vector<int> Container;
Container::const_iterator begin() const { return c.begin(); }
Container::const_iterator end() const { return c.end(); }
// note that, the above two functions have const modifier
// so inside them Container c is treated as const
// i.e. c.begin() and c.end() return const_iterator
// warning: a call to this member func may invalidate iterators
void add_element(int x) { c.push_back(x); }
private:
Container c;
};
int main() // client code
{
ClassA a;
a.add_element(2);
a.add_element(1);
// you can access elements of your vector...
ClassA::Container::const_iterator i;
i = std::find(a.begin(), a.end(), 1);
// ...but can not modify them, the following line will not compile
*(a.begin()) = 0; // ERROR: Cannot modify a const object
}
Robert Rybarczyk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Feb 24, 2004 7:25 pm Post subject: Re: STL Vectors & Memory |
|
|
[email]googleaddress (AT) yahoo (DOT) co.uk[/email] (Patrick) wrote in message
news:<94740f05.0402230919.60d59bbc (AT) posting (DOT) google.com>...
| Quote: | In class *ClassA* below I have an STL Vector *vec* as a member
variable of the class.
Do I have to create a destructer, and somehow deallocate the memory
from *vec*, or is this handled automatically?
|
It's all automatic. The destructors of all sub-objects (members or base
classes) of your class will automatically be called.
| Quote: | Also I want to allow a client of *ClassA* to be able to view the
elements of the vector. Returning a reference to *vec* would be bad
OO programming as i would be returning a reference to a private member
of the class.
|
Looking at it that way, allowing a client of ClassA to view the elements
of the vector probably isn't very OO either:-).
| Quote: | I was thinking of using a method that would return an iterator over
the Vector i.e.
vector<int>::const_iterator ClassA::getIterator()
{ return vec.begin();
}
However i realised then that STL iterators dont have a reference to
the last element in the container, so this isnt viable. Also this is
pretty much the bad OO programming in the sense that while its a const
iterator and the Vector itself cant be modified, the elements of the
vector can be modified, i.e. once again allowing a client to modify
private data of the class.
|
STL iterators work in pairs. You would never have a getIterator()
function. You might have a begin() and an end() function.
Conceptually, whether you have a pair of functions returning iterators,
or a single function returning a reference to the vector, its pretty
much the same thing. I tend to use iterators, thus:
class ClassA
{
public:
typedef std::vector< int >::const_iterator
iterator ;
iterator begin() const ;
iterator end() const ;
} ;
I also give the weakest guarantees possible in the class specification.
In this case, for example, I might document that ClassA::iterator is a
forward iterator. Even though, for the moment, it is really a random
access iterator. This way, I keep my options more or less open for the
future.
| Quote: | Is there a design pattern or some construct of allowing the client to
view elements of the vector in a "read-only" fashion, while not
violating OO principles?...other than copying the entire vector
|
Providing a const reference or const iterators only allows read-only
access. What more do you want?
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Nicola Musatti Guest
|
Posted: Wed Feb 25, 2004 11:57 pm Post subject: Re: STL Vectors & Memory |
|
|
"Ivan Vecerina" <please_use_web_form (AT) ivan (DOT) vecerina.com> wrote
| Quote: | "Patrick" <googleaddress (AT) yahoo (DOT) co.uk> wrote in message
news:94740f05.0402230919.60d59bbc (AT) posting (DOT) google.com...
[...]
Is there a design pattern or some construct of allowing the client to
view elements of the vector in a "read-only" fashion, while not
violating OO principles?...other than copying the entire vector
Using generic programming, a possible solution is to add
a member function such as:
template<class Fun
Fun applyToEach( Fun f )
{ return std::for_each( items_.begin(), items.end(), f ); }
This is very similar to a Visitor pattern, but without run-time
polymorphism.
And it would also be possible to implement a classic OO-style Enumerator
(which is what I would call an Iterator that has a reference to
the last element of its collection).
|
An alternative might be to provide access by means of an output
iterator by adding a member function such as
template
std::copy(items.begin(),items.end(),oi);
}
The most straightforward use would be:
std::list<int> l;
a.getItems(std::back_inserter(l));
Cheers,
Nicola Musatti
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|