Re: learner's question on populating vector< pair<int, string>* > as
member
subramanian100in@yahoo.com, India wrote:
Consider a class that has
vector< pair<int, string>* > c;
as member data object.
I need to use operator>> to store values into this container
object and operator<< to print the contents of the container.
I have written both these operators as non-friend functions.
The destructor deletes all the pair<int, string> pointers in
the vector.
My doubt is that I am using a store_pair() function which
allocates memory for each pair<int, string> pointer and stores
into the container; but the dtor deletes these pointers
thereby releasing the memory.
And what do you doubt about that? (I have doubts about the
wisdom of storing pointers, rather than the objects themselves,
given that std::pair has value semantics, but that's a different
issue.)
Kindly let me know if the approach in this program is correct.
Here is the full program:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
class Test
{
public:
Test();
~Test();
typedef pair<int, string> pair_type;
typedef vector<pair_type*> container_type;
void store_pair(const pair_type& arg);
const container_type& container() const { return c; }
I also have a lot of doubts about exposing the implementation
like this. If you're going to do this, you might as well make
the container public, and be done with it.
private:
container_type c;
};
Test::Test() : c()
{
}
void Test::store_pair(const pair_type& arg)
{
pair_type* p = new pair_type(arg.first, arg.second);
c.push_back(p);
What's wrong with simply:
c.push_ back( new pair_type( arg ) ) ;
?
}
Test::~Test()
{
for (container_type::iterator it = c.begin(); it != c.end(); +=
+it)
{
delete *it;
*it = 0;
Formally (but only formally), this is undefined behavior. You
must set the pointer in the container to null before the delete.
Practically, of course, there'll never be an implementation
where it will cause any problems, so I wouldn't worry about it.
For that matter, I wouldn't worry about setting the pointer to
null, since there'll never be an implementation where not doing
so will cause problems either, so I wouldn't worry about that
either.
}
}
istream& operator>>(istream& is, Test& obj)
{
while (is)
{
int x;
string str;
is >> x >> str;
if (is)
{
Test::pair_type temp(x, str);
obj.store_pair(temp);
}
}
return is;
}
The real question is what semantics you want. Generally
speaking, I have my doubts about the format you're inputting; I
can't think of a context where it would be appropriate. But
what is appropriate depends on the application. Until you've
defined the format, it's impossible to say whether this is
correct or not.
ostream& operator<<(ostream& os, const Test& obj)
{
for (Test::container_type::const_iterator it =
obj.container().begin();
it != obj.container().end();
++it)
os << (**it).first << " " << (*it)->second << endl;
Why the two different ways to access the pair? Choose one, and
use it consistently. (I'd use the second, but that's more a
question of personal preference.)
return os;
}
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34