I am trying to get the value of x and y after the user input,
placed the values in a consturctor,
and using getX() and getY() method in Point.cpp to do some calculations but the thing is, it always returns X:0 Y:0 and I have no idea why. My code is below
Point.cpp
#include <iostream>
#include "Point.h"
using namespace std;
Point::Point(int x,int y) {
setX(x);
setY(y);
}
int Point::getX() {
return x;
}
int Point::getY() {
return y;
}
void Point::setX(int x) {
this->x = x;
}
void Point::setY(int y) {
this->y = y;
}
void Point::someMethods() {
x = getX();
y = getY();
cout << "X:" << x << "Y:" << y;
// do some methods here after getting the x and y cords;
}
Point.h
#ifndef Point_Point_h
#define Point_Point_h
class Point {
private:
int x,y;
public :
Point() {
x = 0;
y = 0;
}//default consrructor
Point(int x,int y);
int getX();
int getY();
void setX(int x);
void setY(int y);
void someMethods();
};
#endif
In the main function, you have the statement
Point Point(x,y);
When I think you meant
Point point(x,y);
As it is, the point.someMethods() call below is using the global point object declared just before the main function, which I think is the problem.
You are calling the someMethods() on the point object which is global which was created using the default constructor which initializes the x and y values to 0.
Use the below code.
#include <iostream>
#include "Point.h"
using namespace std;
int main()
{
int x,y;
cout << "Please Enter x-Cordinate"<< endl;
cin >> x;
cout << "Please Enter y-Cordinate" << endl;
cin >> y;
Point point(x,y);
//just putting here in main to show that X and Y value isn't passed
point.someMethods(); // This should print the proper X and Y values
}
You need to notice that you do point.someMethods(), while never actually changing point to be using x and y.
int x,y;
int main()
{
cout << "Please Enter x-Cordinate"<< endl;
cin >> x;
cout << "Please Enter y-Cordinate" << endl;
cin >> y;
Point point(x,y);
//just putting here in main to show that X and Y value isn't passed
point.someMethods(); <-- the output will always be X:0 Y:0 no matter what value the user input
}
Will work because now the point is created with x and y (notice I've deleted the point declaration from before the main function. You could alternatively declare it there and use its set functions).
That happens because you have 2 "Point" objects in your program. One is instantiated here: "Point point;" and the other is instantiated here: "Point Point(x,y);".
In the end you're calling "point.someMethods();" using the first object, which was constructed using the default constructor, thus having x and y set as 0.
I believe in this case you should remove "Point point;" instantiation from the global namespace, and change the name of your "Point Point(x,y);" to "Point point(x,y);". Then it'll work as expected:
#include <iostream>
#include "Point.h"
using namespace std;
int x,y;
int main()
{
cout << "Please Enter x-Cordinate"<< endl;
cin >> x;
cout << "Please Enter y-Cordinate" << endl;
cin >> y;
Point point(x,y);
//just putting here in main to show that X and Y value isn't passed
point.someMethods(); <-- the output will always be X:0 Y:0 no matter what value the user input
}
You need to change Point Point(x,y); to Point point(x,y) and delete Point point;
Problem
You are not modifying your zero-initialized variable
Point point; // <---- only this variable is zero-initialized
int main()
{
// ...
//just putting here in main to show that X and Y value isn't passed
point.someMethods(); //<-- the output will always be X:0 Y:0 no matter what value the user input
// ^^^^^ <--- again, still zero
}
Solution
Instead do something like:
int main()
{
Point point(1,2); // <-- or read from std::cin
//just putting here in main to show that X and Y value isn't passed
point.someMethods(); //<-- value the user input
}
Live Example
Note
Just because you have the c++11 here, the canonical way to write your constructors would be
class Point
{
private:
int x = 0; // any constructor which does explicitly set x or y
int y = 0; // will take these in-class initializer values
public:
// default constructor uses in-class initializer
Point() = default; // sets to (0,0)
// other constructor does NOT use setters but initialization list
Point(int a, int b): x{a}, y{b} {} // sets to (a,b)
};
Related
#include<iostream>
using namespace std;
class Nokta{
private:
int x,y;
public:
Nokta();
Nokta(int, int);
int getX();
int getY();
void setX(int);
void setY(int);
};
Nokta::Nokta(){
cout << "parametresiz kurucu cagrildi\n";
}
Nokta::Nokta(int x, int y=0){
this->x = x;
this->y = y;
cout << "parametreli kurucu cagrildi\n";
}
int Nokta::getX(){
return x;
}
int Nokta::getY(){
return y;
}
void Nokta::setX(int _x){
x=_x;
}
void Nokta::setY(int _y){
if(_y > 5)
y=_y;
else
y = 2;
}
int main(){
Nokta *ptr;
cout << ptr << " " << &ptr << " "<< ptr->getX() << endl;
return 0;
}
Nokta* ptr; A constructor function is not called when I type it, but I can print one of its variables to the screen. ptr->getX() works. I guess this value is randomly assigned, but how is it done in the background before an object is created?
Output
0x401b6b 0x61ff0c 1528349827
ptr is just a variable that should hold an address to a Nokta object. But you did not create a Nokta object for the pointer to point to.
Nokta noktaObj = Nokta(someNum, someNum)
Nokta* ptr = &noktaObj
When you don't initialize the object, and try to access data (like ptr->getX()), you're just getting whatever garbage happens to be in memory in that location.
I would like to know how to define a variable in one function and access and change it in another function.
For example:
#include <iostream>
void GetX()
{
double x = 400;
}
void FindY()
{
double y = x + 12;
}
void PrintXY()
{
std::cout << x;
std::cout << y;
}
int main()
{
GetX();
FindY();
PrintXY();
}
How would I access these variables from all the functions? (Obviously for this to work in real life I wouldn't need so many functions, but I think this is a nice simple example). Thanks in advance for your help!
Use function parameters to pass values to functions and return values to return results:
#include <iostream>
double GetX()
{
return 400;
}
double FindY(double x)
{
return x + 12;
}
void PrintXY(double x, double y)
{
std::cout << x;
std::cout << y;
}
int main()
{
double x = GetX();
double y = FindY(x);
PrintXY(x, y);
}
Since the question was tagged with C++, here is another option:
#include <iostream>
class Sample
{
public:
void FindY()
{
y = x + 12;
}
void PrintXY()
{
std::cout << x;
std::cout << y;
}
private:
double x = 400, y;
};
int main()
{
Sample s;
s.FindY();
s.PrintXY();
}
You want to define a variable in one function : That means you are making the variable local to that function.
You want to access and change that local variable from another function. This is not usual. Technically possible but can be done with better resource management/design.
*You can make the variable your class member and play with it.
*You can share a variable by making it global as well.
*In Tricky way :
double &GetX()
{
static double x = 400;
return x;
}
// We are accessing x here to modify y
// Then we are modifying x itself
// Pass x by reference
double &AccessAndChangeX(double& x)
{
static double y;
y = x + 12; // We are accessing x here and using to modify y.
// Let's modify x
x = 100;
return y;
}
void PrintXY(double x, double y)
{
std::cout << x;
std::cout << y;
}
int main()
{
double &x = GetX(); // Take the initial value of x. 400.
double &y = AccessAndChangeX(x);
//Print initial value of x and value of y(generated using x)
PrintXY(x, y);
// X was modified while AccessAndChangeX(x). Check if x was changed!
std::cout << "\n" << "What is the value of x now : " << GetX();
}
1st, make x, y as static, so that these exist when the function returns..
2nd, get reference, modify or do something outside the function..
#include <iostream>
double &GetX()
{
static double x = 400;
return x;
}
double &FindY( double x )
{
static double y;
y = x + 12;
return y;
}
void PrintXY(double x, double y )
{
std::cout << x;
std::cout << y;
}
int main()
{
double &x = GetX();
double &y = FindY( x );
// Now you can modify x, y, from Now On..
// .....
PrintXY( x, y );
}
By the way, I donot recommend this style of code..
#include <iostream>
using namespace std;
double Default = 0;
class Vector
{
public:
Vector(double x, double y, double z);
double X, Y, Z;
double fVctr[3];
};
Vector::Vector(double x,double y,double z)
{
this->X = x;
this->Y = y;
this->Z = z;
this->fVctr[0] = X;
this->fVctr[1] = Y;
this->fVctr[2] = Z;
}
this part throws me the error no default constructor esists
class Edge
{
public:
Vector vectA;
Vector vectB;
Edge(Vector _vectA , Vector _vectB){
this->vectA = _vectA;
this->vectB = _vectB;
}
};
int main()
{
Vector Vertex(0,2,5);
// Debug
cout << Vertex.X <<"\n"<< endl;
cout << Vertex.Y << "\n" << endl;
cout << Vertex.Z << "\n" << endl;
}
Given a constructor
Constructor( ... )
{ // A
...
};
at Point A, all members are getting default initialized, since they cannot be uninitialized, when we start into the code of the constructor. To initialize members without default constructor or const members, you have to use the so-called member initializer list.
In your example this would look like this:
Edge(Vector _vectA, Vector _vectB) : vectA(_vectA), vectB(_vectB)
{ // This can be empty, since everything is done, but it has to exist nonetheless.
}
It is good practice to use the member initializer list for as much as possible, since you can save yourself some default initializations and every member is in the state it should be before you do anything with it.
PS: You don't have to reference members by this->member, just write member. Also, please do not use using namespace std;.
the reason is in your Edge class Constructor.
Edge(Vector _vectA , Vector _vectB){
this->vectA = _vectA;
this->vectB = _vectB;
}
the Arguments need a default value. for this, you can Overload your constructor in Vector class.
like this :
Vector::Vector(double x=0,double y=0,double z=0)
{
this->X = x;
this->Y = y;
this->Z = z;
this->fVctr[0] = X;
this->fVctr[1] = Y;
this->fVctr[2] = Z;
}
or like this :
Vector::Vector()
{
this->X = 0;
this->Y = 0;
this->Z = 0;
this->fVctr[0] = X;
this->fVctr[1] = Y;
this->fVctr[2] = Z;
}
As a matter, of course, you didn't use the Edge class in Main Procedure. so you can safely delete or comment that class and prevent the compile error of your code.
When returning a reference to the object on which the function is invoked, the returned reference can be used to chain function calls on a single object.
Here, I am applying the same concept. But I am getting different output if I initialize objects differently.
First example:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1(5, 5);
// Chained function calls. All calls modify the same object
// as the same object is returned by reference
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Output is 10 and 20, which is correct.
However, output is not correct for the second example:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
Output is 10 and 0.
Why? I think both are the same, the output of the second program should be 10 and 20 too. What is the reason it's different?
The difference is that the second version of your program returns by value. This means that the second call (i.e. setY) is performed on a copy of obj1, not on the obj1 itself. That's why only X ends up being set, but not Y.
In your first program, on the other hand, the setters return their results as a reference. This means that no copy is being made, so setY is called on the same object as setX, not on its copy.
When I try using a method to return a private variable, it seems the value changes from since the object was constructed. Here is my code and output.
main.cpp
#include <iostream>
#include "coordinate.h"
using namespace std;
int main()
{
Coordinate c(1, 1);
cout << c.getX() << endl;
}
coordinate.cpp
#include "coordinate.h"
#include <iostream>
using namespace std;
Coordinate::Coordinate(int x, int y)
{
x = x;
y = y;
cout << x << endl;
}
coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
class Coordinate
{
private:
int x;
int y;
public:
Coordinate(int x, int y);
int getX() { return x; }
int getY() { return y; }
};
#endif
Your constructor is assigning to its arguments instead of the object's private fields. Use an initialization list, or explicitly qualify the assignment targets with this, or pick different argument names:
Coordinate::Coordinate(int x, int y) : x(x), y(y) {
cout << x << endl;
}
or
Coordinate::Coordinate(int x, int y) {
this->x = x;
this->y = y;
cout << x << endl;
}
or
Coordinate::Coordinate(int xVal, int yVal) {
x = xVal;
y = yVal;
cout << x << endl;
}
Within the constructor, x refers to the argument, rather than the member variable, so x = x is an assignment of the argument to itself. The member variables remain uninitialised.
You can avoid this problem by using a member-initialiser-list or by explicitly referring to the member variable through this->x.
Coordinate::Coordinate(int x, int y) : x(x), y(y)
{
cout << this->x << endl;
}
Did you try assigning the values to private member variables using this pointer like this?
Coordinate::Coordinate(int x, int y)
{
this->x = x;
this->y = y;
cout << x << endl;
}
or what you can do is to change the parameter names in constructor to avoid using this pointer
Coordinate::Coordinate(int a, int b)
{
x = a;
y = b;
cout << x << endl;
}
Try :
Coordinate::Coordinate(int x, int y)
{
this->x = x;
this->y = y;
cout << this->x << endl;
}
First time you get value of x = 1 because its value of argument 'x' that got print. but second time you got it wrong because, member variable x never get any value assigned.
The problem is with these assignments:
x = x;
y = y;
You are actually assigning the constructor parameters x and y to themselves, and not from the parameters to the object's x and y members.
Also, this line
cout << x << endl;
prints the constructor parameter x and not the object's x member.
You are hiding members x and y by using the same names as the constructor parameters' names. Referencing the names x and y without qualifying them would refer to the parameters and not the object's members.
You can solve this problem by doing something like this. In that, I prefixed the member variables with m_. You can also do some other similar techniques.
uselease replace the variable names as :
class Coordinate
{
private:
int a;
int b;
public:
Coordinate(int x, int y)
{
a = x;
b = y;
cout << x << endl;
}
int getX() { return a; }
int getY() { return b; }
};
Actually the compiler is getting confused which value of x to use, plz use some other variables in private section. Otherwise you can use this to resolve this also as:
Coordinate(int x, int y)
{
this->x = x;
this->y = y;
cout << x << endl;
}
With these code:
x = x;
y = y
you are assign x and y to themselves.
Coordinate::Coordinate(int xVal, int yVal)
{
x = xVal;
y = yVal;
cout << x << endl;
}
is okay.
the best way is:
Coordinate::Coordinate(int xVal, int yVal):x(xVal),y(yVal)
{
cout << x << endl;
}
As others have pointed out
Coordinate::Coordinate(int x, int y)
{
x = x;
y = y;
This is a condition called "shadow variables". The values "x" and "y" in the function prototype shadow the member variables, and thus "x = x" assigns the value of parameter x to the parameter x.
Compilers like GCC and Clang will warn you about this. MSVC doesn't because Microsoft's API is a bit messy and they use a hell of a lot of the symbol table :)
A widely used way to avoid this is prefixes. "m_" for "member", "g_" for "global", "s_" for "static".
class Coordinate
{
// by saying 'class' instead of 'struct',
// you declared the initial state to be "private".
int m_x;
int m_y;
...
Coordinate::Coordinate(int x, int y)
: m_x(x)
, m_y(y)
{}
Some folks take this a step further and use a prefix - or suffix - for parameter names; I picked up adding "_" from several Open Source projects I worked on.
Coordinate::Coordinate(int x_, int y_)
: m_x(x_)
, m_y(y_)
{
int x = m_x; // assign from member value
int y = y_; // assign from parameter
std::cout << x << ", " << y << std::endl;
}