члены класса и функции c

#c #class #function

#c #класс #функция

Вопрос:

Я изучаю c . Я написал небольшую программу, которая должна вычислить энергию системы из 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») в энергетической функции. Я пробовал, как вы видите, energy (часть частиц), но, похоже, Particle не определена в этой области.

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

Я компилирую с помощью теста g -o energy.cpp main.cpp

Спасибо.

Комментарии:

1. #include заголовок. Для второго бита вы получите нарушения доступа, если вы выйдете за пределы диапазона массива.

Ответ №1:

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

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

 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», я объявил «часть» как массив с двумя элементами. Однако в «main» я могу использовать более двух членов, например part [3], part [4] … Почему я мог бы использовать больше членов, чем те, которые я объявил?

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

Комментарии:

1. Мне нужно сделать видимой структуру «Particle» в другом файле с именем initial.cpp . Я скопировал строки: #включить «data.h» «Часть частиц [2];» в initial.cpp но компилятор говорит несколько определений части. Если я помещу эти две строки либо energy.cpp или initial.cpp программа работает нормально. Но почему мне не нужно объявлять «Particle part [2]» в обоих файлах?

2. вы только #include "data.h" ! Particle part[2]; вам нужно записать только один раз, а не в несколько .cpp файлов. Почему вам не нужно его объявлять? Мы устанавливаем его как extern в заголовке. Мы устанавливаем переменную «один раз» в cpp-файле. Все остальные файлы, которые будут включать заголовок, будут «совместно использовать» память переменной. Обычно вы просто создаете a data.h с extern Particle part[2]; и a data.cpp , который будет иметь #include "data.h" и Particle part[2]; . Тогда все остальные файлы main.cpp и energie.cpp будут просто #include "data.h" . Оба cpp файла смогут получить доступ к Particle part[2]

Ответ №2:

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

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

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

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

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

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

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

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

Ответ №3:

С классом можно делать все, что угодно …

 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 Vector3amp; GetPos() const { return m_pos; }

   void SetMass(double mass) { m_mass = mass; }
   void SetCharge(double charge) { m_charge = charge; }
   void SetPos(const Vector3amp; 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;                                                                                                                                                                                                               
};   
  

Ответ №4:

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

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

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

Комментарии:

1. Я добавил строку включения, но получаю следующие сообщения: energy.cpp : В функции ‘двойная энергия (частица)’: energy.cpp:7:23: ошибка: нет совпадения для ‘operator[]’ в ‘part[0]’ main.cpp : В функции ‘int main()’:main.cpp:15:18: ошибка: запрошено преобразование из ‘Particle *’ в нескалярный тип ‘Particle’

2. @armando заменить double energy(Particle part) на double energy(Particle* part) in main.cpp amp; energy.cpp

Ответ №5:

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

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

Ответ №6:

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

 #include "data.h"
  

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

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

Конечно, я бы сказал, что то, что вы действительно хотите создать, — это функция-член для энергии внутри частицы. Прямо сейчас вы используете классы в виде структуры в стиле C. Это означает, что вам не хватает возможности использовать все объектно-ориентированные преимущества, которые может предложить 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 , которые это позволяет (например, объявление массива нулевого размера для неизвестных размеров и назначение ему блока памяти).

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