C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

STL Vectors & Memory

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Patrick
Guest





PostPosted: Mon Feb 23, 2004 7:46 pm    Post subject: STL Vectors & Memory Reply with 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.

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





PostPosted: Tue Feb 24, 2004 3:31 am    Post subject: Re: STL Vectors & Memory Reply with quote



"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





PostPosted: Tue Feb 24, 2004 1:36 pm    Post subject: Re: STL Vectors & Memory Reply with quote



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





PostPosted: Tue Feb 24, 2004 7:25 pm    Post subject: Re: STL Vectors & Memory Reply with quote

[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





PostPosted: Wed Feb 25, 2004 11:57 pm    Post subject: Re: STL Vectors & Memory Reply with quote

"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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.