CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Mar 2005
    Posts
    55

    Question Class inside the same class

    Hi,

    I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
    Code:
    class particle {
        int x;                 // particle location
        int y;
        int z; 
    
        particle *neighbour;      // I have taken one neighbour particle for simplicity to illustrate the problem.               
                                  // Actually,  it is vector of particles.  
    };
    Is it valid? Any other idea will be appreciated.
    Thanks.

  2. #2
    Join Date
    Oct 2008
    Location
    Singapore
    Posts
    195

    Re: Class inside the same class

    You can have multimap of particles:
    http://www.cplusplus.com/reference/stl/multimap/

    Code:
    class particle {
        int x;                 // particle location
        int y;
        int z; 
    };
    
    std::multimap<particle> particle_tree;

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Class inside the same class

    Quote Originally Posted by manojg View Post
    Hi,

    I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
    Code:
    class particle {
        int x;                 // particle location
        int y;
        int z; 
    
        particle *neighbour;      // I have taken one neighbour particle for simplicity to illustrate the problem.               
                                  // Actually,  it is vector of particles.  
    };
    Is it valid? Any other idea will be appreciated.
    Thanks.
    You may use a class inside itself under 2 conditions:
    1 - You don't include it by value, or else your class would have infinite size
    2 - You only reference it by pointer semantics, ie: you don't need anything more than a forward declaration:

    Code:
    class particle {
        int x;                 // particle location
        int y;
        int z; 
    
        particle *neighbour; //OK: Pointer to a particle type.
        particle neighbor_by_value; //KO: contains itself by value
        vector<particle> vector_of_particles; //KO: Requires the full definition of particle
        vector<particle*> vector_of_star_particles; //OK
    };
    I'm not actually 100&#37; sure you can't use a vector<particle>, but that wouldn't really work as a solution anyways, since you want references (pointers) to the neighbors.

    I'm not entirely sure your approach is the best. I'm not sure the gas particles should be the ones keeping track of their neighbors. Maybe an external multimap would be a better design? Just an idea, but I wouldn't know. I think you should take the time to check your options before committing to your design though.
    Last edited by monarch_dodra; August 24th, 2010 at 01:33 AM.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  4. #4
    Join Date
    Dec 2009
    Posts
    145

    Re: Class inside the same class

    In multiagent systems, if you code in traditional C style, it becomes really hard to
    1.read
    2.maintain, modify
    3.debug
    etc
    If this is an academic project then its harder for your students to expand (I know, I used to be a student)
    I am thinking if it's possible to separate them completely into different classes then use OOP features to wrap them up (no pointer to itself), a vector of agents will be used later to calculate forces and coordinates among them easier.
    STL is powerful, other libraries like Boost are awesome, but I don't abuse them. For most of the problems I run into myself, such containers and container-like holders as set, map and vector are enough for me...perhaps I know still less but I am satisfied somehow...

  5. #5
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Class inside the same class

    Quote Originally Posted by manojg View Post
    Hi,

    I am writing a simulation code. I have a class called "particle" which hold gas particles. Each gas particle has its neighbouring gas particles. And its neighbouring gas particles have their own neighbouring particles. I tried to write the "particle" class like below to hold neighbouring particles also:
    Code:
    class particle {
        int x;                 // particle location
        int y;
        int z; 
    
        particle *neighbour;      // I have taken one neighbour particle for simplicity to illustrate the problem.               
                                  // Actually,  it is vector of particles.  
    };
    Is it valid? Any other idea will be appreciated.
    Thanks.
    I don't think your design is the best idea. Consider what happens when you have a high number of particles. Each particles holds a vector of pointers to particals, when you add one more particle to the system, you will need to run through all particles to figure out which particles are neighbours and then update each appropriate neighbour vector.

    Furthermore, you are not currently considering particle momentum, which you will need to do for a proper simulation. In this case, everytime you move to the next time frame, you will need to recalculate which particles each particle considers its neighbours. For a high number of particles your simulation computation time will increase significantly past a linear increase.

    It would perhaps be a better design if you had a container of particles.

    Code:
    std::vector<particle> particles_
    Where from a data model point of view Particle is defined as follows

    Code:
    struct particle
    {
      Location loc;
      Momenta m;
    };
    and Location is defined as

    Code:
    struct location
    {
      int x;
      int y;
      int z;
    };
    and momenta is defined as:

    Code:
    struct momenta
    {
       double mass;
       float p_x;
       float p_y;
       float p_z;
    };
    Note that particle physics uses four-momenta:

    http://en.wikipedia.org/wiki/Four-momentum

    However, since you are not dealing with relativistic calculations, it makes more sense in your case to use the particle rest mass. You can then calculate velocities as

    Code:
     v_x = p_x/m;
     v_y = p_y/m;
     v_z = p_z/m;
    Anyway, effectively if you do the above, then your vector of particles will be a snapshot in time. You will be able to use the momenta and location of each particle to make efficient elastic collision calculations with neighbouring particles using discrete changes in time. You will also be able to make particle tracks.

    I'm not sure if this is more than you want, but anyway, that's for you to decide.
    Last edited by PredicateNormative; August 24th, 2010 at 05:20 AM.

  6. #6
    Join Date
    Mar 2005
    Posts
    55

    Thumbs up Re: Class inside the same class

    Hi all,

    Thanks everybody for your helpful suggestions. I figured out to do this way which similar to previous one:

    I created a base class for just one gas particle, "singleParticle", and another class for gas particle including its neighbours, "particle", which is derived from "singleParticle".
    Code:
    class singleParticle {
        double x;
        double y;
        double z;
    };
    Code:
    class particle : public singleParticle {
          particle *neighbour;   // it is a pointer, so do not have infinite loop
    };
    So, every gas particle is of type "particle".

    Thanks.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Class inside the same class

    While that may work, it doesn't look like the most logical use of inheritance. You're saying that every particle IS-A singleParticle, which is fine; but since you didn't give singleParticle a virtual destructor, it's unsafe to view a particle solely as a singleParticle if it's dynamically allocated.

  8. #8
    Join Date
    Mar 2005
    Posts
    55

    Re: Class inside the same class

    HI Lindley,

    Thanks for reminding me. I have assigned a virtual distructor but I forgot to write in detail here.
    Code:
    class singleParticle {
        private:
            double x;
            double y;
            double z;
            
         public:
              singleParticle();
              virtual ~singleParticle();
              ........ other methods
    };
    Code:
    class particle : public singleParticle {
          private:
              particle *neighbour;   // it is a pointer, so do not have infinite loop
    
          public:
              particle();
              virtual ~particle();
              ........... other methods
    };

  9. #9
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: Class inside the same class

    Quote Originally Posted by PredicateNormative View Post
    I don't think your design is the best idea. Consider what happens when you have a high number of particles. Each particles holds a vector of pointers to particals, when you add one more particle to the system, you will need to run through all particles to figure out which particles are neighbours and then update each appropriate neighbour vector.

    Furthermore, you are not currently considering particle momentum, which you will need to do for a proper simulation. In this case, everytime you move to the next time frame, you will need to recalculate which particles each particle considers its neighbours. For a high number of particles your simulation computation time will increase significantly past a linear increase.

    It would perhaps be a better design if you had a container of particles.

    Code:
    std::vector<particle> particles_
    Where from a data model point of view Particle is defined as follows

    Code:
    struct particle
    {
      Location loc;
      Momenta m;
    };
    and Location is defined as

    Code:
    struct location
    {
      int x;
      int y;
      int z;
    };
    and momenta is defined as:

    Code:
    struct momenta
    {
       double mass;
       float p_x;
       float p_y;
       float p_z;
    };
    Note that particle physics uses four-momenta:

    http://en.wikipedia.org/wiki/Four-momentum

    However, since you are not dealing with relativistic calculations, it makes more sense in your case to use the particle rest mass. You can then calculate velocities as

    Code:
     v_x = p_x/m;
     v_y = p_y/m;
     v_z = p_z/m;
    Anyway, effectively if you do the above, then your vector of particles will be a snapshot in time. You will be able to use the momenta and location of each particle to make efficient elastic collision calculations with neighbouring particles using discrete changes in time. You will also be able to make particle tracks.

    I'm not sure if this is more than you want, but anyway, that's for you to decide.
    I like the design with Location and Momenta but I don't think that the vector of 'neighbors' isn't a bad idea but it could be added to the particle class as an additional - though redundant - means to improve calculations.

    Assume you add each particle in a sorted way to the all particles vector. The sort criteria might be the distance to the origin (0, 0, 0). Then new particles easily could be added to the all vector by using a binary search. Also the neighbors could be found fastly that way. When a single particle was moving you could check all neighbors much faster than you could do with the all vector alone. And you could find potential new neighbors more easily cause canditates for the new neighbors you could find by evaluating the neighbors of those of neighbor particles you were moving towards to (where the distance to would decrease or where the distance vector changes orientation).

    A quite different modeling would be to store the particles as a graph with vertices and edges. While a vertex is equivalent to a particle you may have edges for all neighbor relations between the particles. The advantage of that approach is that you can use all algorithms and methods of graph theory - though I actually don't know whether that was valuable for a simulation of gas particles.

  10. #10
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Class inside the same class

    Quote Originally Posted by manojg View Post
    Hi all,

    Thanks everybody for your helpful suggestions. I figured out to do this way which similar to previous one:

    I created a base class for just one gas particle, "singleParticle", and another class for gas particle including its neighbours, "particle", which is derived from "singleParticle".
    Code:
    class singleParticle {
        double x;
        double y;
        double z;
    };
    Code:
    class particle : public singleParticle {
          particle *neighbour;   // it is a pointer, so do not have infinite loop
    };
    So, every gas particle is of type "particle".

    Thanks.
    This looks even worst. What's wrong with:

    Code:
    class singleParticle {
        double x;
        double y;
        double z;
         std::vector<particle*> neighbours;
    };
    What is the point of splitting things up?

    If your answer is to keep single particles instances smaller, then it is a bad reason (that I'll only take the time to explain, if it was)
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  11. #11
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Class inside the same class

    Quote Originally Posted by itsmeandnobodyelse View Post
    I like the design with Location and Momenta but I don't think that the vector of 'neighbors' isn't a bad idea but it could be added to the particle class as an additional - though redundant - means to improve calculations.

    Assume you add each particle in a sorted way to the all particles vector. The sort criteria might be the distance to the origin (0, 0, 0). Then new particles easily could be added to the all vector by using a binary search. Also the neighbors could be found fastly that way. When a single particle was moving you could check all neighbors much faster than you could do with the all vector alone. And you could find potential new neighbors more easily cause canditates for the new neighbors you could find by evaluating the neighbors of those of neighbor particles you were moving towards to (where the distance to would decrease or where the distance vector changes orientation).

    A quite different modeling would be to store the particles as a graph with vertices and edges. While a vertex is equivalent to a particle you may have edges for all neighbor relations between the particles. The advantage of that approach is that you can use all algorithms and methods of graph theory - though I actually don't know whether that was valuable for a simulation of gas particles.
    I agree that something has to be responsible for monitoring which particles are neighbours, but I was thinking that could be done by a class external to the container. I was thinking that a statistical cost (or weighted distance) could be calculated in some kind of association matrix, and that matrix would supply the closest neighbouring particles. Perhaps the statistical cost could be a combination of position and momenta information, possibly calculated using a Kalman filter... but then maybe I'm going too far?

  12. #12
    Join Date
    Mar 2005
    Posts
    55

    Re: Class inside the same class

    Hi monarch_dodra,

    You are right, it is just splitting the class. I wrote this way to solve one of my problem temporarily (I was writing the data in a file, a type of formate which can also write class.). But it crashes when I do not split the class. By splitting, I can write all particle as a "singleParticle". This way it does not crash. However, I have no clue how efficient it will be compared to other methods. Still working.

    Thanks.

  13. #13
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Class inside the same class

    Hopefully you aren't doing file IO by the widespread but incorrect "cast to char*" method.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured