члены класса и функции с ++ - PullRequest
0 голосов
/ 07 октября 2011

Я учу с ++.Я написал небольшую программу, которая должна вычислять энергию системы N частиц.До сих пор у меня есть три небольших файла:

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);                                                                                                               
}   

У меня два вопроса:

1) Я хочу сделать видимой частицу Класса в функции «энергия».Другими словами, я хочу использовать переменные функции класса (со значениями, указанными в «main») в функции энергии.Я пробовал, как вы видите энергию (Particle part), но кажется, что Particle не определена в этой области.

2) Как вы видите в «data.h», я объявил «part» как массив с двумя членами,Однако в «main» я могу использовать более двух членов, например part [3], part [4] ... Почему я мог использовать больше членов, чем я объявил?

Я компилирую с g ++ -o test energy.cpp main.cpp

спасибо.

Ответы [ 6 ]

1 голос
/ 07 октября 2011

Все виды вещей, которые вы можете сделать с классом ...

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 голос
/ 07 октября 2011

1) Я хочу сделать видимой частицу Класса в функции «энергия».Другими словами, я хочу использовать переменные функции класса (со значениями, указанными в «main») в функции энергии.Я пробовал, как вы видите, энергию (Часть Частицы), но кажется, что Частица не определена в этой области.

Если я вас правильно понимаю ... Вы хотите иметь

Particle part[2];

для использования в main.cpp и energy.cpp?Если да .. измените это на:

extern Particle part[2];

и в energy.cpp добавьте это:

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

, и вы сможете использовать

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

2) Как вы видите в «data.h», я объявил «part» как массив с двумя членами.Однако в «main» я могу использовать более двух членов, например part [3], part [4] ... Почему я мог использовать больше членов, чем я объявил?

Потому что это C / C ++?нет проверки диапазона.Ты можешь делать все, что захочешь.Но если вы это сделаете, результат будет неожиданным.

1 голос
/ 07 октября 2011

1) Я хочу сделать видимой частицу Класса в функции «энергия».

Вы должны #include "data.h" в файле energy.cpp.

2) Как вы видите в «data.h», я объявил «part» как массив с двумя членами.

Возможно, вам не следовало этого делать,по двум причинам:

  • Позже вы научитесь избегать объявления глобальных объектов.Это допустимо (и часто правильно), но пока вы не научитесь, вы, вероятно, захотите объявить ее как локальную переменную в main.

  • Вы не должны объявлять глобальные объектыв заголовочных файлах, так как они будут объявлены в каждой единице перевода, которая включает в себя заголовочный файл.

Однако в «main» я могу использовать более двух членов, длячасть экземпляра [3], часть [4] ... Почему я мог использовать больше членов, чем я объявил?

Индексируя за пределами массива, вы вызываете «неопределенное поведение».Система может делать почти все (например, сбой, отправка Биллу Гейтсу электронной почты, начало глобальной термоядерной войны и т. Д.).Среди бесконечного разнообразия вещей, включенных в «неопределенное поведение», наиболее запутанным является, кажется, работа.Это то, что произошло в вашем случае.Вы не должны рассчитывать на то, что он продолжает работать.

1 голос
/ 07 октября 2011

Вам нужно #include "data.h" в energy.cpp.Включения обрабатываются только для каждого файла, поэтому energy.cpp не может видеть заголовок без этого.

РЕДАКТИРОВАТЬ: В вашей функции параметр part выходит за рамки глобального определения part, поэтому part в вашей функции не является массивом.Вы хотите:

cout << part.mass << "\n";   
0 голосов
/ 07 октября 2011

Чтобы ответить на первый вопрос, вы можете просто включить data.h в energy.cpp.

#include "data.h"

К сожалению, вы создали «деталь» в глобальном пространстве, поэтому каждый файл .cpp будет создавать ее независимо.Когда он будет ссылаться на объектные файлы, он увидит, что существует множество ссылок на «часть».Здесь вы можете использовать ключевое слово "extern", а в data.h вы просто объявите его как внешнюю переменную.Или, поскольку вы ссылаетесь только на «part» в main.cpp, вы можете просто перенести туда глобальное определение, и проблема будет решена.

Теперь, когда дело доходит до того, что вы сделали в energy.cpp,Вы создали отдельную переменную, также называемую «часть».Когда применяются правила области видимости, это означает, что компилятор будет принимать локальное определение поверх глобального определения.Поскольку вы передаете объект класса, а не массив классов, вы получите ошибку компилятора при ссылке на него как «part [0] .mass».Вместо этого, почему вы беспокоитесь о ценности другой частицы, а не частицы, в которой вы прошли?Если вам нужна масса конкретного объекта Particle, то вы должны написать это как «part.mass»

Конечно, я бы сказал, что вы действительно хотите создать функцию-член для энергии внутри Particle.Прямо сейчас вы используете классы в стиле структуры Си.Это означает, что вам не хватает возможности использовать все объектно-ориентированное совершенство, которое может предложить C ++.Вы можете сделать это следующим образом

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; }                                                                                                      
};

Чтобы ответить на ваш второй вопрос, C ++ предполагает, что вы знаете больше о памяти, чем он.В GCC (AFAIK) нет проверки границ, потому что память может быть выделена где угодно в любое время и также освобождена.Однако, в отличие от других языков, вы должны сами управлять памятью.Это позволяет оптимизировать и обманывать C ++ (например, объявлять массив нулевого размера для неизвестных размеров и назначать ему блок памяти).

Приветствия!

0 голосов
/ 07 октября 2011

1> Включить «data.h» в energy.cpp

2> Массив C ++ очень примитивен, не имеет никакой проверки границ, поэтому вы можете получить доступ к части [4]. Но естьнет никакой гарантии, что это будет работать каждый раз. Большинство программ может зависать во время выполнения, жалуясь на повреждение памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...