Reputation: 1213
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
Upvotes: 3
Views: 4384
Reputation: 24249
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;
}
Upvotes: 0
Reputation: 295
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;
}
Upvotes: 0
Reputation: 280207
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;
}
Upvotes: 9
Reputation: 718
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;
}
Upvotes: 0
Reputation: 17708
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.
Upvotes: 0
Reputation: 1336
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;
}
Upvotes: 1
Reputation: 40613
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;
}
Upvotes: 2
Reputation: 1066
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.
Upvotes: 0