Erik Wikstr?m <Er***********@telia.com> wrote:
On 2006-06-01 12:52, Cl*******@hotmail.com wrote: I have created a class Particle which has a method toString() that
prints out all the useful information. In my main program I create an
array of these objects and once I've fiddled with them a bit I want to
use the toString() method on them all.
Is there a way of defining toString() so that I don't have to loop
through all of the particles printing each individually.
The code might explain it better than I can so the relevant part of the
class is below:
class particle{
string toString(){
ostringstream os;
os << pos.toString << '\t'
<< Vel.toString << '\t'
<< Npos.toString << '\t'
<< w.toString << '\n'
return os.str();
} ;
}
I then create some particles:
particle* myParticles = new particle[n];
and would like to be able to write
cout << myParticles.toString();
rather than:
for(int i;i<n;i++){
cout << myParticles[i].toString();
}
No, not if you just put them in an array. You could create your own
array-like container class to put them in and overload the []-operator
and such but to do all that just so that you don't have to write two
lines whenever you want to print the content is a bit much. A better
alternative would be to create a function with the for-loop and just
call the function with the array as argument.
Another alternative is to use operator overloading. You can overload
operator<< for your type, something like (untested):
std::ostream& operator<<(std::ostream& os, const particle& p)
{
// The below is what it would look like if you have an
// appropriate operator<< for each member instead of using
// toString
os << pos << '\t'
<< Vel << '\t'
<< Npos << '\t'
<< w; // I usually leave off the last '\n' to mimic output
// other native types
return os;
}
(You may need to make it a friend function if it accesses private or
protected parts of your class).
If you do it this way, then you can do (for example):
particle p = /* whatever */;
// ...
o << p << '\n';
where 'o' can be any std::ostream, like std::cout or a std::ofstream.
In addition, this will let you use std::copy (in <algorithm>) for
output. Here is a complete example with a couple different uses:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
class Particle {
// dummy variables for illustration
std::string name_;
double vel_;
int pos_;
public:
Particle()
: name_("empty")
, vel_(0.0)
, pos_(42)
{ }
friend std::ostream& operator<<(std::ostream&, const Particle& p);
};
std::ostream& operator<<(std::ostream& os, const Particle& p)
{
os << p.name_ << '\t'
<< '(' << p.vel_ << ", "
<< p.pos_ << ')';
return os;
}
std::ostream& operator<<(std::ostream& os, const std::vector<Particle>& pv)
{
std::copy(pv.begin(), pv.end(), std::ostream_iterator<Particle>(os, "\n"));
return os;
}
int main()
{
int n = 3;
Particle* myParticles = new Particle[n];
// better would be std::vector
std::cout << "Array:\n";
std::copy(myParticles,
myParticles + n,
std::ostream_iterator<Particle>(std::cout, "\n"));
std::cout << "\nVector:\n";
std::vector<Particle> myParticles2(3);
std::copy(myParticles2.begin(),
myParticles2.end(),
std::ostream_iterator<Particle>(std::cout, "\n"));
std::cout << "\nVector2:\n";
std::cout << myParticles2;
}
--
Marcus Kwok
Replace 'invalid' with 'net' to reply