class members and functions c++ - 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.

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.

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.

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

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>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!

Related

C++: implementing a global constant whose value is given by the user

First of all, let me say I have read similar threads on how to initialize a global variable or how to properly implement global constants. Nevertheless, these questions did not really help me with my concrete problem, as also haven't any other ressources I've consulted. The problem is the following.
I (have to) declare in a header file header.h a variable that must be constant and used by the main function in main.cpp as well as other functions defined in a another file functions.cpp (that are previously declared in header.h). The problem is this constant is a runtime constant, whose value is given by the user. How should I proceed?
I think my best shot was to do as follows. In header.h
// Header guard
namespace n
{
// Some forward declarations
extern const double mu; // The constant that should be initialized by the user.
// Some other declarations
}
then in functions.cpp
#include "header.h"
namespace n
{
// Some definitions here
double function_that_uses_mu(double a, double b)
{
// Some code using mu
return somedouble;
}
// Some other definitions
}
finally main.cpp
#include "header.h"
#include <iostream>
int main()
{
// Some code
double value_of_mu{};
std::cin >> value_of_mu;
// Validity check
extern const double n::mu{ value_of_mu };
// More code
return 0;
}
The problem is that compilation fails due to the fact that error: ‘mu’ has both ‘extern’ and initializer. However, if I tried mu = value_of_mu I would obviously get an error because I would be assigning to a const value (not initialising it). So I don't know how to proceed, or what's wrong with my code. There are two mandatory facts I must respect:
Functions/global-consts definitions, functions/global-consts declarations and main must be split in the three aforementioned files.
mu is to be defined as a constant shared by all three files.
Is this possible? How?
EDIT:
I think my problem is that an exten variable can't be initialised inside a function, but if this is so, I don't see how I do what I'm trying to.
Think about it: If a value needs to be set during the lifetime of a program, it's not really a constant. So, you shouldn't try to pretend it's a constant by declaring it as const. If you don't want the program to accidentally change its value, you have to protect it in some other way, such as making it a private member variable of a class. That way, you can restrict access to only return the value of mu as a const.
// muholder.h
class muholder
{
private:
double m_value;
public:
muholder (double ivalue): m_value(ivalue) {}
double const &value() const { return m_value; }
};
// workflow_envelope.h
class workflow_envelope
{
private:
muholder m_mu;
public:
workflow_envelope (double imu): m_mu(imu) {}
bool validity_check();
double method_that_uses_mu (double a, double b) const { return a*m_mu.value()/ b; }
void run(); // any "more code" goes in here.
};
// main
#include "workflow_envelope.h"
#include <iostream>
int main()
{
// Some code
double value_of_mu;
if (std::cin >> value_of_mu)
{
// Validity check
workflow_envelope workflow(value_of_mu);
if (workflow.validity_check())
{
workflow.run();
return 0;
}
}
return 1;
}
When you initialize a variable, you can't specify extern. This should work instead:
int main()
{
// Some code
double value_of_mu{};
std::cin >> value_of_mu;
// Validity check
using namespace n;
const double mu = value_of_mu; // no extern specifier
// More code
return 0;
}

variable has initializer but incomplete type C++

I am new to C++. I have this code to create a struct, to show the usage of mutable keyword in C++.
#include <iostream>
using namespace std;
int main()
{
struct
{
mutable double radius;
double PI = 3.142;
double getArea()
{
return (PI * radius * radius);
}
} circle;
const struct circle c1 = {2.0};
circle.radius = 7;
cout << "Area is " << circle.getArea() << endl;
return 0;
}
But I get the following error message when compiling:
error: variable const main()::circle c1 has initializer but incomplete type
Error is at c1 in the line const struct circle c1 = {2.0};. Can anyone point me out the error here.
You don't define a structure named circle, you define a variable named circle. This variable can not be used as a type.
You should do e.g. struct circle { ... }; to define the structure as a type. Then you could do
const circle c1 = { 2.0 };
c1.radius = 7;
std::cout << c1.getArea() << '\n';
There are a few other problems, most notable you don't declare the getArea function as const which means you can't call it on const objects.
When you put the name circle after the right brace at the end of the struct definition, you're declaring a variable.
Put it at the start, after the word struct, to declare a type.
I.e.
struct circle
{
// ...
};
In other news:
You'll need to declare getArea() as const to be able to call it on a const instance, i.e. double getArea() const.
You don't need the return 0; at the end, because that's the default for main. There is no such default for other functions. main is special.
In order to use cout unqualified (as it seems you want to) you can add using namespace std; at the start of the code; it's usually placed after the includes.
mutable is usually not used to allow outside code to treat part of an object as always non-const.
Instead it's used as a device to more easily let a class implementation have some non-const state also when the object appears to be const to outside code. That's called logical constness. For example, the object might cache the result of an expensive computation, even when it's const.
In C++17 and later mutable can also be applied to lambda expressions, where it yields a lambda that can change its state (captured values).

C++: no member named 'xPos' in 'Star'

Trying to compile my code in Xcode, but I am obviously running into some problems as I get the error in the title. Here is the code for my header file called "myClasses.h":
#ifndef myClasses_h
#define myClasses_h
class Star
{
public:
Star(int x,int y)
{
int xPos = x;
int yPos = y;
}
};
#endif
So I obviously want a constructor for Star so I can declare a Star object like this:
Star sol(10,30);
Then the code in my "main.cpp":
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include "myClasses.h" //includes the Star class
bool checkOverlap(Star check, int a, int b)
{
double diffX = a - check.xPos;
double diffY = b - check.yPos;
double checkDist = sqrt( pow( diffX,2.0 ) + pow( diffY,2.0) );
if( checkDist > 20 )
return true;
else
return false;
};
int main()
{
//some other code here with no errors
};
Here in the main file I get the error, so I am lost as to what is going wrong? Am I using incorrect syntax to access the object's member variables? Shouldn't the code below print 10:
Star sol(10,30);
cout << sol.xPos
If not, how do I rewrite my class so it behaves like that or how do I properly access the member variables in the constructor?
You need to declare the variables in your class, you can't do that in the body of the constructor as those will be temporary variables not associated with the class instance. This will leave the xPos and yPos as their default values (which is 0) which is probably not what you want. Try something like this instead:
class Star
{
public:
int xPos;
int yPos;
Star(int x,int y):
xPos(x), yPos(y) //initializing the variables here
{
}
};
I've used a member initializer list here to initialize the members.
It's worth noting that this is likely not the best design for a class, you probably want to make xPos and yPos private along with some functions to change those values. You probably want to read up about encapsulation. Essentially you want to hide away information so that people don't need to know the internals of how your classes work in order to use them. This big benefit is that this lets people use your code without needing to worry about the internals of how your code works and lets them keep using your code without having to change their code even if some of those internal details happen to change over time. Imagine the hassle if you had to know exactly how your network card driver was programmed in order to write an application that used the network. It would be a big pain, you might have to change your code whenever you updated the other code, however because this driver code has (hopefully) been encapsulated you don't need to worry about these details in order to use that code. The code and classes you write are no different, think about the people who will use them, try to make it easy for them to use your code.
A possibly better design would be to do something like this:
class Star
{
private:
int xPos;
int yPos;
public:
Star(int x,int y):
xPos(x), yPos(y) //initializing the variables here
{
}
int get_xPos(){
return xPos;
}
int get_yPos(){
return yPos;
}
};
Now in your main code you change:
Star sol(10,30);
cout << sol.xPos;
To:
Star sol(10,30);
cout << sol.get_xPos();
The benefits of doing it this way really start to become more obvious when you get larger software or you have to deal with changes. For example later on the code changes and we decide to store the coordinates in a coordinates struct:
struct coords{
int xPos;
int yPos;
}
class Star
{
private:
coords Pos;
public:
Star(int x,int y):
Pos{x,y} //initializing the variables here
{
}
int get_xPos(){
return Pos.xPos;
}
int get_yPos(){
return Pos.yPos;
}
};
The original code would break:
Star sol(10,30);
cout << sol.xPos; //There's no xPos anymore
but with our new design this:
Star sol(10,30);
cout << sol.get_xPos();
Works just like before! We only needed to change the code in one place in the getter function get_xPos() and everthing will keep working just like it did before we made the changes.
Declare member variables:
class Star
{
public:
int xPos;
int yPos;
Star(int x,int y)
{
xPos = x;
yPos = y;
}
};

What is the difference between using the friend keyword, and using a member function to modify private variables inside of a class?

As the question asks...
What is the difference between:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
private:
int m_a;
friend void set_a(MyClass &a);
};
void set_a(MyClass &a)
{
std::cout << a.m_a << std::endl;
a.m_a = 500;
std::cout << a.m_a << std::endl;
}
int main(void) {
MyClass my_class_instance;
set_a(my_class_instance);
system("pause");
}
and:
class MyClass
{
public:
MyClass(){
m_a = 0;
}
void set_a(){
std::cout << this->m_a << std::endl;
this->m_a = 500;
std::cout << this->m_a << std::endl;
}
private:
int m_a;
};
int main(void) {
MyClass my_class_instance;
my_class_instance.set_a();
system("pause");
}
Is it simply the preferred structure of the function, or are there real, measurable differences? From what I can tell, both functions achieve the same results in all circumstances, except if you had multiple overloads for the first example, that took different types of objects.
As the C++ FAQ says: Use a member when you can, and a friend when you have to.
There are situations where making friend a free function is preferable, most situations related to the fact that the first parameter of a member function is always of that class (Its the hidden *this parameter).
One example is arithmetic operators overloading:
Suppose you write a complex class which represents complex numbers. Using a member operator+() you could write expressions like complex + float, but not float + complex. But you could do it with the free form of the operator+:
class complex
{
...
friend complex operator+( float f , complex c );
};
This whole question comes down to "Why would I use friends in C++?". The answer is that when used properly, friends enhance encapsulation. This is an FAQ:
Do friends violate encapsulation?
Your example is too short and too abstract, of course. Some better, real life examples I could think of from the top of my head involve iterators. You may have many iterator objects referring to only one container object, and you may want the iterator to be able to access private member variables of the container. At the same time, you don't want the container to expose those variables to the rest of the world.
Such a design could be perfectly implemented with the friend feature.
Many people defend that making accessor methods, you can in a later stage of development put barriers to the incorrect access to the member variables (or even change the member variables totally) without breaking your (correct) clients.
One classical case is of a
class ComplexNumber {
double real, imaginary;
public:
double re() { return re; }
double setRe(double v) { return re = v; }
// and so on ...
};
one day you discover, in some maintenance, that you need the polar coordinates for that number, so you add the methods
double rho() { /* calculate rho */ }
double theta() { /* calculate theta */ }
double setRho(double v) { /* calculate real, imaginary, based on the new rho */ }
and so on.
Later yet, you discover that the users of the class use far more often polar than Cartesian coordinates for complex numbers, and that the conversions have been the bottleneck of a performance problem, so you ditch real and imaginary and store rho and theta, and change the getter and setter methods for the new -- more efficient -- storage for rho, theta, re, im, and so on. All the clients of your class will recompile without problems, because you changed your implementation but kept your interfaces stable.

Handling lots of variable declarations

I am implementing a class and I have a function that does things using lots of variables that need to be declared and initialised.
I'd like the variable declarations not to clutter the function and do something like:
doFunction(){
declare();
//Do things with variables declared in declare()
}
void declare(){
//declare lots of variables here
}
This does not work as the variables are scoped to declare() and aren't seen by doFunction(). What's a sensible way to handle this problem?
Since each of the variables that you declare must be assigned a value, you should combine declaration with initialization. In other words, instead of
int x;
double y;
std::string z;
x = 1;
y = 2.0;
z = "3";
do this:
int x = 1;
double y = 2.0;
std::string z("3");
This is pretty much as far as you can push this approach with locals: declaring variables is an essential part of the function body, you cannot (and arguably, should not) move it to a remote location.
You can also move the member function into a nested private class, move the local variables into the class, and do calculations there:
class specialCalc {
int x;
double y;
std::string z;
specialCalc() : x(1), y(2.0), z("3") {}
public:
int calculate() {
...
}
};
void doFunction() {
specialCalc calc;
cout << calc.calculate() << endl;
}
PS: I am deliberately not mentioning preprocessor-based solutions because they would negatively impact readability.
I'm not really advocating this, but:
struct Declare
{
int x;
float y;
char z;
vars() :x(1),y(3.14),z('z') {}
};
void doFunction()
{
Declare vars;
// use vars.x, vars.y and vars.z as your variables
}
You have a number of choices:
1) Get over it. If you need lots of variables, you'll need to suffer the fact they need to be declared somewhere.
2) Put them into a class or in a structure as a member variable so you can declare them in the .h file and they'll be invisible in the .C/.cpp file.
3) Aggregate them into an array, and declare only the array and initialize them in a for() loop or something. This really only works if they're all a similar type and you don't do silly things like "index 4" is my "counter object for this", and "index 5" is my "thing I'm going to print to the screen" as then you loose the name associated with the variable itself, which is rather helpful when reading the code later (of course).
4) put them in a define statement somewhere else:
#define MYVARS int a; char b[1024]; ...
void funstuff() {
MYVARS
}
5) Modify an IDE so that it can hide/collapse the variable declarations when you're viewing the code.
Note that of all of these choices, number 1 is still probably the right answer :-)