applying a method to an array of objects.

C

Cleverbum

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.toString();
}
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

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

Erik Wikström
 
C

Cleverbum

good idea, thanks.
Erik said:
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.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.

Erik Wikström
 
M

Marcus Kwok

Erik Wikstr?m said:
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.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::eek:stream& operator<<(std::eek:stream& 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::eek:stream, like std::cout or a std::eek:fstream.
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::eek:stream& operator<<(std::eek:stream&, const Particle& p);
};



std::eek:stream& operator<<(std::eek:stream& os, const Particle& p)
{
os << p.name_ << '\t'
<< '(' << p.vel_ << ", "
<< p.pos_ << ')';

return os;
}



std::eek:stream& operator<<(std::eek:stream& os, const std::vector<Particle>& pv)
{
std::copy(pv.begin(), pv.end(), std::eek:stream_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::eek:stream_iterator<Particle>(std::cout, "\n"));


std::cout << "\nVector:\n";
std::vector<Particle> myParticles2(3);
std::copy(myParticles2.begin(),
myParticles2.end(),
std::eek:stream_iterator<Particle>(std::cout, "\n"));

std::cout << "\nVector2:\n";
std::cout << myParticles2;
}
 
M

Marcus Kwok

Marcus Kwok said:
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::eek:stream_iterator<Particle>(std::cout, "\n"));

Ack! There should be a

delete[] myParticles;

here. This is why I avoid using raw dynamic arrays, and prefer
std::vector.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top