我正在学习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)我想在函数“energy”中看到Class粒子。换一种说法, 我想使用类函数的变量(使用“main”中给出的值) 在能量函数。 我已经尝试过你看到能量(粒子部分),但似乎没有定义粒子 在那个范围内。
2)正如您在“data.h”中看到的,我将“part”声明为具有两个成员的数组。然而, 在“主”中我可以使用两个以上的成员,例如部分[3],部分[4] ......为什么我 可以使用比我声明的成员更多的成员吗?
我正在使用g ++ -o test energy.cpp main.cpp进行编译
感谢。
答案 0 :(得分:1)
您需要{energy}内的#include "data.h"
。包含仅在每个文件的基础上处理,因此没有它,energy.cpp无法看到标题。
编辑:在您的函数中,参数part
超出范围part
的全局定义,因此函数中的part
不是数组。你想要:
cout << part.mass << "\n";
答案 1 :(得分:1)
1)我想在函数“energy”中看到Class粒子。
您应该在#include "data.h"
文件中energy.cpp
。
2)正如您在“data.h”中看到的,我将“part”声明为具有两个成员的数组。
你可能不应该这样做,原因有两个:
稍后您将学习以避免声明全局对象。这样做是合法的(通常也是正确的),但在您学习之前,您可能希望将其声明为main
中的局部变量。
您不应在头文件中声明全局对象,因为它们将在包含头文件的每个翻译单元中声明。
但是,在“main”中我可以使用两个以上的成员,例如part [3],part [4] ...为什么我可以使用比我声明的更多的成员?
通过索引超出数组末尾,您已调用“未定义的行为”。该系统可以自由地做任何事情(例如,崩溃,向比尔盖茨发送电子邮件,开始全球热核战争,&amp; c)。在“未定义的行为”中包含的各种各样的事物中,最令人困惑的是 - 似乎有效。这就是你的情况。你不应指望它继续看似有用。
答案 2 :(得分:1)
1)我想在函数“energy”中看到Class粒子。换句话说,我想在能量函数中使用类函数的变量(在“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 ++?没有范围检查。你想做什么,就可以做什么。 但如果你这样做,结果将是意料之外的。
答案 3 :(得分:1)
你可以用班级做各种各样的事情......
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;
};
答案 4 :(得分:0)
1&gt;在energy.cpp中包含“data.h”
2 - ; C ++数组是非常原始的,它没有任何绑定检查,因此你可以访问part [4]。但是不能保证它每次都能工作。大多数时间程序可能会在运行时抱怨内存时崩溃是腐败的。
答案 5 :(得分:0)
要回答第一个问题,您可以在energy.cpp中简单地包含data.h。
#include "data.h"
不幸的是,您已在全局空间中创建了“part”,因此每个.cpp文件将独立创建它。当它链接目标文件时,它将看到存在对“部分”的多个引用。你可以在这里使用“extern”关键字,在data.h中,你只需将它声明为外部变量。或者,因为你只在main.cpp中引用“part”,你可以在那里移动全局定义并解决问题。
现在,当谈到你在energy.cpp中所做的事情时,你已经创建了一个名为“part”的单独变量。当应用范围规则时,这意味着编译器将在全局定义上采用本地定义。由于您传递的是类对象而不是类数组,因此在引用它时会遇到编译器错误,如“part [0] .mass”。 相反,你为什么关心其他粒子的价值而不是你传入的粒子?如果你想要特定粒子对象的质量,那么你应该像“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 ++技巧(比如为未知大小声明一个零大小的数组并为其分配一块内存)。
干杯!