简体   繁体   中英

class members and functions c++

I'm learning c++. I have written a small program which should compute the energy of a N particle system. Up to now I have three small files:

data.h:

    class Particle {                                                                                                                      
        public:                                                                                                                       
        double mass;                                                                                                                  
        double charge;                                                                                                                
        double posx,posy,posz;                                                                                                        
};                                                                                                                                    

        Particle part[2];  

main.cpp:

#include <iostream>                                                                                                                   
#include "data.h"                                                                                                                     
using namespace std;                                                                                                                  

double energy(Particle part );                                                                                                        

int main ()                                                                                                                           
{                                                                                                                                     
        double sd;                                                                                                                    
        part[0].mass = 10.0;                                                                                                          
        part[4].mass = 90.0;                                                                                                          
        cout << part[0].mass << "\n";                                                                                                 
        cout << part[4].mass << "\n";                                                                                                 

        sd = energy(part);                                                                                                            
        cout << "sd" << sd <<  "\n" ;                                                                                                 
        return 0;                                                                                                                     
}    

energy.cpp:

#include <iostream>                                                                                                                   
using namespace std;                                                                                                                  

double energy(Particle part)                                                                                                          
{                                                                                                                                     
        cout << part[0].mass << "\n";                                                                                                 
        double dummy;                                                                                                                 
        dummy = 2.0;                                                                                                                  
        return (dummy);                                                                                                               
}   

I have two questions:

1)I want to make visible the Class particle in the function "energy". In other words, I want to use the variables of the class function (with the values given in "main") in the energy function. I have tried as you see energy(Particle part) but it seems Particle is not defined in that scope.

2)As you see in "data.h" I declared "part" as an array with two members. However, in "main" I can use more than two members, for instance part[3],part[4]... Why I could use more members than those I declared?

I am compiling with g++ -o test energy.cpp main.cpp

thanks.

You need to #include "data.h" in energy.cpp. Includes are only processed on a per-file basis, so energy.cpp can't see the header without that.

EDIT: In your function, the parameter part , out-scopes the global definition of part , so the part in your function is not an array. You want:

cout << part.mass << "\n";   

1)I want to make visible the Class particle in the function "energy".

You should #include "data.h" in the file energy.cpp .

2)As you see in "data.h" I declared "part" as an array with two members.

You probably shouldn't have done that, for two reasons:

  • You will learn later to avoid declaring global objects. It is legal (and often correct) to do so, but until you learn, you probably want to declare it as a local variable in main .

  • You should not declare global objects in header files, since they will then be declared in every translation unit that includes the header file.

However, in "main" I can use more than two members, for instance part[3],part[4]... Why I could use more members than those I declared?

By indexing beyond the end of the array, you have invoked "undefined behavior". The system is free to do almost anything (for example, crash, send Bill Gates an email, start a global thermo-nuclear war, &c). Among the infinite variety of things included in "undefined behavior" is the most confusing one of all -- appear to work. That is what happened in your case. You should not count on it continuing to appear to work.

1)I want to make visible the Class particle in the function "energy". In other words, I want to use the variables of the class function (with the values given in "main") in the energy function. I have tried as you see energy(Particle part) but it seems Particle is not defined in that scope.

If I understand you right.. You want to have

Particle part[2];

to be use able in main.cpp and in energy.cpp ? If yes.. change this to:

extern Particle part[2];

and in energy.cpp add this:

#include "data.h"
Particle part[2];

and you will be able to use

double energy()                                                                                                          
{              
        //main.cpp will have same part                                                                                                                       
        cout << part[0].mass << "\n";                                                                                                 
        double dummy;                                                                                                                 
        dummy = 2.0;                                                                                                                  
        return (dummy);                                                                                                               
}

2)As you see in "data.h" I declared "part" as an array with two members. However, in "main" I can use more than two members, for instance part[3],part[4]... Why I could use more members than those I declared?

Because it's C/C++ ? no range checks. You can do what ever you want. But if you do, the result will be unexpected.

All sorts of things you can do with a class ...

struct Vector3
{
    double m_x, m_y, m_z;  
};

class Particle
{                                                                                                                      
public:    
   double ComputeEnergy() { // return answer }

   double GetMass() const { return m_mass; }
   double GetCharge() const { return m_charge; }
   const Vector3& GetPos() const { return m_pos; }

   void SetMass(double mass) { m_mass = mass; }
   void SetCharge(double charge) { m_charge = charge; }
   void SetPos(const Vector3& pos) { m_pos = pos; }
   void SetPos(double x, double y, double z)
   {
      m_pos.m_x = x;
      m_pos.m_y = y;
      m_pos.m_z = z;
   }
private:                                                                                                                   
   double m_mass;                                                                                                                  
   double m_charge;   
   Vector3 m_pos;                                                                                                                                                                                                               
};   

1>Include "data.h" in energy.cpp

2> C++ array is very primitive it doesn't has any bound checking so you were able to access part[4].But there is no guarantee that it will work every time.Most of the time program may crash during run-time complaining the memory is corrupt.

To answer the first question, you could simply include data.h in energy.cpp.

#include "data.h"

Unfortunately, you've created "part" in the global space and so each .cpp file will independently create it. When it goes to link the object files, it will see that multiple references to "part" exist. What you can do here is use the "extern" keyword and in data.h, you would simply declare it as an external variable. Or, because you only reference "part" in main.cpp, you could just move the global definition in there and the problem is solved.

Now, when it comes to what you have done in energy.cpp, you've create a separate variable also called "part". When scoping rules are applied, it means that the compiler is going to take the local definition over the global definition. Since you are passing a class object and not a class array, you'll get a compiler error when referencing it like "part[0].mass". Instead, why are you concerned about the value of the other particle and not the particle you passed in? If you want the mass of a particular Particle object, then you should write it like "part.mass"

Of course, I would argue that what you really want to create is a member function for energy within Particle. Right now, you are currently using classes in a C style struct way. This means that you are missing the ability to use all the object oriented goodness that C++ has to offer. You could do it like this

class Particle 
{                                                                                                                      
protected:                                                                                                                       
    double mass;                                                                                                                  
    double charge;                                                                                                                
    double posx,posy,posz; 
public:
    void SetMass(double newMass) { mass = newMass; } 
    void SetCharge(double newCharge) { charge = newCharge; } 
    void SetX(double newX) { posX = newX; } 
    void SetY(double newY) { posY = newY; } 
    void SetZ(double newZ) { posZ = newZ; } 
    double GetEnergy() { return 2.0; }                                                                                                      
};

To answer your second question, C++ assumes you know more about the memory then it does. There is no bounds checking in GCC(AFAIK) because the memory could be allocated anywhere at any time and deallocated as well. However, unlike other languages, you have to manage the memory yourself. There's a lot of optimizations and C++ trickery that this enables(like declaring a zero sized array for unknown sizes and assigning a block of memory to it).

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM