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

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

Related

How does Data Encapsulation actually happen in OOP?

I'm learning C++.
Came across data encapsulation and data hiding at a website, check out the following piece of code:
#include<iostream.h>
#include<conio.h>
class sum {
private: int a, b, c;
public:
void add() {
clrscr();
cout << "Enter any two numbers: ";
cin >> a >> b;
c = a + b;
cout << "Sum: " << c;
}
};
void main() {
sum s;
s.add();
getch();
}
NOW. As it says here that:
The main advantage of using of encapsulation is to secure the data from other methods, when we make a data private then these data only use within the class, but these data not accessible outside the class.
What happens underneath the code, what does the compiler do that makes it inaccessible to other classes? And in the given example what was the reason behind defining a,b and c as private.
What were they trying to achieve by hiding "just the declarations of the three variables"? Because anyone can see that inside public three numbers being used are a,b, and c - first two for input and third one for output.
How is this possible that the data under private can't be accessed
outside the class?
Compiler makes sure you don't. If you try to access say a outside class, your code will not compile.
And in the given example what was the reason behind defining a,b and c
as private.
It could be anything! But as a result, a,b and c are not accessible outside members of class.
Basically you want to hide some variables in your class for the sake of consistency. So that you or your clients can not produce a code that makes unwanted and uncontrolled changes.
Updates:
What happens underneath the code, what does the compiler do that makes
it unaccessible to other classes?
Compiler implementation check for access level while producing code. If there is something wrong, you will get a syntax error and no machine code will be generated from your file.
And in the given example what was the reason behind defining a,b and c
as private; what were they trying to achieve by hiding "just the
declarations of the three variables"? Because anyone can see that
inside public three numbers being used are a,b, and c - first two for
input and third one for output.
You don't hide variables in your class to make them invisible to others. Private variables that are not intended to be used from outside of the class can be marked as private to limit the potential for coding errors.
As an example consider following class:
class rectangle {
public:
int width;
int height;
int area;
};
void something_important(const rectangle& r) {
// ...
}
What happens if I pass a rectangle of width -10, height 0 and area of -15? There could be a plane crash or a nuclear weapon launched to some wrong target... So I will make sure my rectangles are always valid:
class rectangle {
public:
void set_width(int w) {
if(w) width = w;
else width = 0;
area = width*height;
}
int get_width() const {return width;}
void set_height(int h) {
if(w) height = h;
else height = 0;
area = width*height;
}
int get_height() const {return height;}
int get_area() const {return area;}
private:
int width;
int height;
int area;
};
So no one can make a rectangle of negative height or width, and no one can make a rectangle having a wrong area. (you can not actually change area directly)
I hope it makes sense for you now.
What happens underneath the code, what does the compiler do that makes it unaccessible to other classes?
Not much. The compiler doesn't protect against access to the data. It protects against access to the name of the data. For instance:
void foo(class bar&, int&);
class bar {
int i = 0;
public:
void baz() {
foo(*this, i);
}
};
void foo(class bar& b, int& i) {
//b.i = 42; // This is an error. b.i is private
i = 42; // This is okay, no matter what the local i refers to
}
In the example above, foo() cannot access b.i by name, because it's a private data member. But it can still modify it if it obtains a reference by other means. The member function baz() which has access to that name, binds it to the reference that foo() accepts. Thus allowing for its modification from outside the class's scope.

Iterating through a vector which contains a custom class C++

I hope someone can help me. In an effort to be more specific about what I really need, and trim down my code, I have changed from having a vector purely of my Class, to having a vector of objects of a new class, of which my original class is a type within.
I hope I have explained myself clearly up until this point. I will show the relevant classes:
class screen_area
{
private:
int my_id, my_x, my_y, my_width, my_height;
bool active=true;
public:
screen_area (int button_id=0, int x=0, int y=0, int width=0, int height=0, bool isactive=true)
{
my_id = button_id;
my_x = x;
my_y = y;
my_width = width;
my_height = height;
active = isactive;
}
~screen_area()
{}
class bet
{
private:
int wager = 0;
int multiplier = 0;
public:
screen_area area;
bet(int wager, int multiplier, screen_area area)
{};
~bet()
{};
There is a little more to them, but this is the bread and butter. Now previously I had used a member function within "screenarea", to return any value I had wanted from a specific object:
int getvalue(int value)
{
switch(value)
{
case 1 :
return my_id;
case 2 :
return my_x;
case 3 :
return my_y;
case 4 :
return my_width;
case 5 :
return my_height;
case 6 :
return active;
}
}
And I have modified a lookup function to use this member function on the screenarea that is a type contained within "bet".
int returnbuttonid(int mousex, int mousey, std::vector<bet> *buttons)
{
for (auto ep : *buttons )
{
if ((ep.area.getvalue(2) > mousex) && (ep.area.getvalue(3) > mousey))
{int id_value = ep.area.getvalue(1);
return id_value;
}
}
}
However... it returns garbage. I'm clearly missing something, but I am going through it logically and it all seems to make sense.
Sorry in advance if it is something simple! And I appreciate that this may seem long winded but I would really appreciate some help!
And just to be super clear... this is how I am calling it:
vector<bet> localbuttons; //Declaration of Vector
load_map("data.dat", &localbuttons); //load buttonmap using function
int buttonpressed = returnbuttonid(100,300, &localbuttons);
In response to a very speedy comment. It's clear that the problem at least starts with an unpublished piece of code. My vector of "bet" is not being filled with the arguments I am passing to it when I try to overload the constructor. I presumed I had corrected the syntax correctly when I created the new class "bet", but after probing the vector it is not showing any data.
In my function load_map:
bool load_map(std::string path, std::vector<bet> *buttons)
{
//setup file
ifstream inputFile( path.c_str() );
//
//The stuff in the middle here is irrelevant
//and I've take it out to make this tidier
buttons->push_back(bet(0,0, screen_area(id,x,y,width,height, true)));
}
return 0;
}
Now the only part of this that has changed since I had this function was working is:
buttons->push_back(bet(0,0, screen_area(id,x,y,width,height, true)));
So I am guessing this is where the problem originates. The variables are not overloading the default screen_area constructor. So when I:
cout << localbuttons[1].area.my_id << endl;
I always see whatever value I place in the default constructor. It is "0" in the constructor I have posted here, but if I change it, it changes correspondingly.
And I shouldn't have said garbage, I was at fault for thinking I had correctly identified the area of the problem, and trying to be concise. So I guess I should be asking first... How can I correctly overload this "screenarea" constructor?
The problem here was in the Constructor of the Bet class.
After having a look here:
http://www.cplusplus.com/doc/tutorial/classes/
I rewrote the constructor in the Bet class:
bet(int w, int m, int button_id=0, int x=0, int y=0,
int width=0, int height=0, bool isactive=true)
: area(button_id, x, y, width, height, isactive),
wager(w), multiplier(m)
{};
My apologies if I wasted anyone time with misdirection, and thanks for the sensible advice from Jonathon Potter.
I'm not sure why I thought you could call constructors within parentheses. My compiler didn't seem to complain about it, but from what I can gather - I was just creating a temporary object.

Have const variables in an object which is used in a vector container

So I am trying to make snake clone.
I have made a BodyPiece class which has certain variables I would like to be const, as they should not change. This was not a problem when I simply created an instance of Bodypiece to test out. However I want to be able to add pieces as the snake grows so I made a vector body variable. As you can see from the code below:
In BodyPiece.h:
#pragma once
#include "D3DGraphics.h"
#include "Keyboard.h"
#include "Direction.h"
class BodyPiece
{
public:
BodyPiece(int xPos, int yPos, Direction* dir);
~BodyPiece();
void Draw(D3DGraphics& gfx);
void UpdateDirection(KeyboardClient& kbd);
void Move();
private:
Direction* dir;
int xPos;
int yPos;
int width = 5;
int height = 5;
int vx = 5;
int vy = 5;
};
In Game.h file
BodyPiece vector body declared:
std::vector<BodyPiece> body;
In Game.cpp file
vector initialised in initialiser list.
body({ {400, 300, &d } })
If I make any variables in BodyPiece const, it will generate an error:
error C2582 'operator=' function is unavailable in class BodyPiece.
My questions here are:
What causes that? I have looked online and have a little bit of an idea but it really is only a little bit.
How can I have const variables, use a vector container(or another type of container if that will help, does not have to be vector) and keep the compiler happy? Or should I just completely change my approach?
Thank you in advance.
The problem is that if you don't have an assignment operator, then the compiler will generate one for you, that does simple shallow copying of the members. However, if you have actual const member variables (and not only default-initialized like yours) then those can't be copied and the compiler can't create an assignment operator.
The simple solution is to make the constants actual constants and also static so they are members of the class and not part of a single object:
class BodyPiece
{
...
static int const width = 5;
static int const height = 5;
};
The only drawback with this is that you need to actually define these member variables, in a single source file:
int const BodyPiece::width;
int const BodyPiece::height;
The other solution is to explicitly create an assignment operator that copies the data needed:
class BodyPiece
{
public:
...
BodyPiece& operator=(BodyPiece const& other)
{
// Copy data from other to this
xPos = other.xPos;
...
return *this;
}
...
};

Initializing/Preparing class objects in separate files before main()

Simply put, I am trying to have textures and other semi-constant objects be prepared within one .h or .cpp file so that they can be used within other files. I want to be able to do something like this:
class Position
{
private:
int x;
int y;
public:
/* constructor, destructor, and other code */
void setPosition(int x, int y) { this->x = x;
this->y = y; }
};
Then, in another file, have something like this:
//otherfile.extension
// I want to be able to declare these objects here...
Position specialPosition1;
Position specialPosition2;
// ...and then be able to do this somewhere where it will keep
// this information for any other file that includes this.
specialPosition1.setPosition(25, 25);
specialPosition2.setPosition(-10, -10);
I want to be able to call their setPosition() method and prepare them within the same file to be used within other files if possible. Or at least be able to set it up so that the information will exist before it is used anywhere else.
If I recall, making them static would not solve this issue; plus I still have no (known) place to call the setPosition to prepare the objects. I have also read up a tad bit on extern, though my knowledge of it is only vague.
How might I be able to prepare these objects before main(), or, to be a bit more precise, what is the "best" way to prepare these objects before they are used in other files?
I don't think you want to call setPosition at all. I think it would be better to initialize them in the constructor. I assume these special positions are constant.
I think you want to declare them as extern in a .h file and then define them in a .cpp:
Position.h:
struct Position {
int x;
int y;
Position(int _x, int _y) : x(_x), y(_y) {}
//...
};
SpecialPositions.h:
#include "Position.h"
extern const Position specialPosition1;
extern const Position specialPosition2;
SpecialPositions.cpp:
#include "SpecialPositions.h"
const Position specialPosition1{25, 25};
const Position specialPosition2{-10, -10};
Main.cpp:
#include "SpecialPositions.h"
#include <iostream>
int main() {
std::cout << specialPosition1.x << "\n";
}
Or you could force compile time constants and use constexpr. Change the Position constructor to be constexpr:
constexpr Position(int _x, int _y) : x(x_), y(_y) {}
And then just define them in the SpecialPositions.h file (no need for SpecialPositions.cpp):
constexpr Position specialPosition1{25, 25};
constexpr Position specialPosition2{-10, -10};

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