This question already has answers here:
Visual Studio 2015 “non-standard syntax; use '&' to create a pointer to member”
(3 answers)
Closed 5 years ago.
I'm new with C++ and I'm currently studying for exams, messing around with C++ in VisualStudio and experimenting a bit. Usuall I work with Java.
I wrote a simple class to see how and if things work:
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
};
I tried 2 simple member functions for x and y to just double the value stored in the x and y variables.
First I tried this:
void doubleX()
{
x *= 2;
};
void doubleY()
{
y *= 2;
};
Then I tried this:
void doubleX()
{
Point::x = 2 * Point::x;
};
void doubleY()
{
Point::y = 2 * Point2::y;
};
Both are put inside the class definition.
While building through VisualStudio it alwas gives me this error warning:
"Error C3867 'Point::doubleX': non-standard syntax; use '&' to create a pointer to member"
Tried to mess around with adress pointers as well but... I don't really have a clue.
I think I know how pointers basically work, but I have no idea how to use it for my case here.
Any quick solution and explanation to this problem?
Thanks in advance!
EDIT: here's my whole code, problem is in the main now
#include "stdafx.h"
#include <iostream>
using namespace std;
class Point
{
public:
int x;
int y;
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void doubleX()
{
x *= 2;
};
void doubleY()
{
y *= 2;
};
};
int main()
{
Point p(1,1);
int &x = p.x;
int &y = p.y;
cout << x << "|" << y;
p.doubleX; p.doubleY; //error message here
cout << x << "|" << y;
cin.get();
}
Maybe you didn't declare the member functions inside the class definition? Here is a full working example based on your class:
#include <iostream>
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void doubleX()
{
x *= 2; /* or this->x *= 2; */
}
void doubleY()
{
y *= 2;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
};
int main()
{
Point p(2, 3);
std::cout << "p.x = " << p.getX() << " | p.y = " << p.getY() << std::endl;
p.doubleX();
p.doubleY();
std::cout << "p.x = " << p.getX() << " | p.y = " << p.getY() << std::endl;
return 0;
}
You can put this in a main.cpp file, compile and run it. I tested it with the g++ compiler and it works fine.
The answer given by Valy is correct. But I would like remind you that C++ offers you another choice of declaring and defining methods, that is declaring method inside the class declaration and defining them outside the class declaration. This enables you to easily separate interface and implementation into .h and .cpp files, respectively, as shown below:
Point.h
class Point
{
private:
int x;
int y;
public:
Point(int arg1, int arg2);
void doubleX();
void doubleY();
int getX();
int getY();
};
Point.cpp
#include "Point.h"
Point::Point(int arg1, int arg2)
{
x = arg1;
y = arg2;
}
void Point::doubleX()
{
x *= 2;
}
void Point::doubleY()
{
y *= 2;
}
int Point::getX()
{
return x;
}
int Point::getY()
{
return y;
}
// PointTest.cpp
#include "Point.h"
int main()
{
// Do something with Point here
Point pt(1, 2);
std::cout << "Original: (" << pt.getX() << ", " << pt.getY() << ")" << std::endl;
pt.doubleX();
pt.doubleY();
std::cout << "After being doubled: (" << pt.getX() << ", " << pt.getY() << ")" << std::endl;
return 0;
}
And, how to compile:
g++ -o PointTest PointTest.cpp Point.cpp
Can't comment due to reputation but it seems vc++ outputs the error message you stated if you try to call
Point::doubleX
Here's a live example of the output:
http://rextester.com/ZLCEW66682
You should create an instance of the class and call the function using parens
In your second set of functions
void doubleX()
{
Point2::x = 2 * Point2::x;
};
void doubleY()
{
Point2::y = 2 * Point2::y;
};
If you want them to be member functions of the class Point, Point::y ... this is not how you should access the member data. Only static member variables can be accessed like that. The correct way is
void doubleX()
{
this->x = 2 * this->x;
};
void doubleY()
{
this->y = 2 * this->y;
};
That is using this pointer.
Related
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..
This question already has answers here:
What is the 'this' pointer?
(8 answers)
Closed 4 years ago.
I confused what does it mean this pointer and how it is used exactly. in the below examples give the same output. What is the difference putting reference operator(&) in the setX and setY functions?
#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;
}
With reference operator
#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;
}
When you return by value, as in
Test setX(int a) { x = a; return *this; }
then you return a copy of the object. And the copy is totally unrelated to the original object.
When you return a reference, you return a reference to the actual object, no copies are made.
And because of this difference the two programs you show should not produce the same output. The first should say that x is equal to 10 (because you set x on the obj1 object) but then you set y on the copy returned by setX, meaning that obj1.y will still be zero. See e.g. this example.
Im having trouble writing my main for a class I created. I created a class called CartesianPoints which I want to use to construct my main with. I have the general structure of my main created but am struggling with the some technical stuff..
Heres what im looking for:
creating an empty vector of CartesianPoint Objects which will be the starting point for the vector
Limit range for x and y values between 10 & -10.
loop to show user the points they just entered and ask what they would like to enter next
the loop above should continue until the break is triggered
here is my header for CartesianPoints
#ifndef MY_CARTESIAN_POINT_H
#define MY_CARTESIAN_POINT_H
#include <iostream> // cin, cout
#include <sstream> // stringstream
#include <cmath> // sqrt()
#include <limits> // INT_MAX
#include <stdexcept> // out_of_range
using namespace std;
class CartesianPoint
{
public:
CartesianPoint(int x = 1, int y = 1) { SetPoint(x, y); }
int GetX() const { return myX; }
int GetY() const { return myY; }
double GetDistanceTo(CartesianPoint pointTo) const;
string ToString() const;
void SetX(int x) { myX = validateCoordinateValue(x); }
void SetY(int y) { myY = validateCoordinateValue(y); }
void SetPoint(int x, int y) { SetX(x); SetY(y); }
static int GetLimit() { return sharedLimit; }
static void SetLimit(int limit) { sharedLimit = abs(limit); }
private:
int myX;
int myY;
static int sharedLimit;
int validateCoordinateValue(int value) const;
};
int CartesianPoint::sharedLimit = INT_MAX;
double CartesianPoint::GetDistanceTo(CartesianPoint pointTo) const
{
int xDelta = pointTo.myX - myX;
int yDelta = pointTo.myY - myY;
return sqrt((xDelta * xDelta) + (yDelta * yDelta));
}
string CartesianPoint::ToString() const
{
stringstream strOut;
strOut << "(" << myX << ", " << myY << ")";
return strOut.str();
}
int CartesianPoint::validateCoordinateValue(int value) const
{
if((value < -sharedLimit || value > sharedLimit))
{
throw out_of_range( "Parameter (" + to_string(value) + ") must be between "
+ to_string(-sharedLimit) + " and " + to_string(sharedLimit) + ".");
}
return value;
}
#endif
here is my main so far
int main()
{
GreetingScreen(); // just a formatting function ive already created
// while loop that makes will give the option to end the program.
while(/* if myX! =10 and myY!= 10 keep doing this loop */ )
{
// try catch for errors....
try
{
cout << "Move from point" /* (0,0)*/ "to where?" << endl;
cout << "X: " << endl;
cin >> x; //point x
cout << "Y: " << endl;
cin >> y; //point y
catch
{
cerr << "could not do this task";
}
}
} // ending of while loop
} // ending of main
You are on the right path, but there are a few things that I do see a concern with.
In your class I don't see where you are using <iostream> I think you can omit it.
You are using using namespace std. It is preferred to just scope out the namespace std::.
About your constructor:
CartesianPoint(int x = 1, int y = 1) { SetPoint(x, y); }
Here you have two default values, there are two options here:
Declare this constructor as explicit
explicit CartesianPoint( int x = 1, int y = 1 ) { SetPoint( x, y ); }
Declare a default and user defined constructors
CartesianPoint() { SetPoint( x, y ); }
CartesianPoint( int x, int y ) { SetPoint( x, y ); } // by value
CartesianPoint( int& x, int& y ) { SetPoint( x, y ); } // by reference
Note - The third constructor my require overloads for the SetPoint function to accept by reference, however if you continue reading below you will see what I've done with your class.
Personally I think the 2nd choice is the better of the two. If you choose to use a constructor with 2 parameters and both have default values and you are not declaring the constructor as explicit; you will run into trouble.
This is why I preferably choose to use the 2nd option of declaring both a default constructor and a user defined constructor. This gives you the flexibility to do any of the following:
{
CartesianPoint p1; // default constructor called
CartesianPoint p2( 5, 6 ); // user defined constructor called.
int x = 5;
int y = 6;
CartesianPoint p3( x, y ); // another user defined constructor called.
}
Now there is something else with the constructor: you are calling a member function to set the point (x,y) This is not really needed. Class's have a member initializer list; use them! You are also using member functions SetX() and SetY() in your member function SetPoint() the extra calls are not needed.
Personally I would write your class as such:
#ifndef MY_CARTESIAN_POINT_H
#define MY_CARTESIAN_POINT_H
// #include <iostream> // cin, cout
#include <sstream> // stringstream
#include <cmath> // sqrt()
#include <limits> // INT_MAX
#include <stdexcept> // out_of_range
// using namespace std;
class CartesianPoint {
private:
int myX;
int myY;
static int sharedLimit;
public:
CartesianPoint() : myX( 0 ), myY( 0 ) {} // I chose 0, but you can choose any default values for (x,y)
CartesianPoint( int x, int y ) :
myX( validate( x ) ),
myY( validate( y ) ) {
}
CartesianPoint( int& x, int& y ) :
myX( validate( x ) ),
myY( validate( y ) ) {
}
int GetX() const { return myX; }
int GetY() const { return myY; }
// by value
void SetX(int x) { myX = validate(x); }
void SetY(int y) { myY = validate(y); }
void SetPoint(int x, int y) {
myX = validate( x );
myY = validate( y );
}
// by reference
void SetX( int& x ) { myX = validate(x); }
void SetY( int& y ) { myX = validate(y); }
void SetPoint( int& x, int& y ) {
myX = validate( x );
myY = validate( y );
}
double GetDistanceTo(CartesianPoint pointTo) const;
string ToString() const;
static int GetLimit() { return sharedLimit; }
static void SetLimit(int limit) { sharedLimit = abs(limit); }
private:
int validate( int value ) const; // by value
int validate( int& value ) const; // by reference
};
int CartesianPoint::sharedLimit = INT_MAX;
double CartesianPoint::GetDistanceTo(CartesianPoint& pointTo) const {
int xDelta = pointTo.myX - myX;
int yDelta = pointTo.myY - myY;
return sqrt((xDelta * xDelta) + (yDelta * yDelta));
}
std::string CartesianPoint::ToString() const {
std::stringstream strOut;
strOut << "(" << myX << ", " << myY << ")";
return strOut.str();
}
int CartesianPoint::validate(int value) const {
return validate( value );
}
int CartesianPoint::validate( int& value ) const {
if((value < -sharedLimit || value > sharedLimit)) {
std::ostringstream stream;
stream << "Out Of Range: Parameter ("
<< + ToString(value)
<< + ") must be between "
<< + ToString(-sharedLimit)
<< + " and "
<< + ToString(sharedLimit)
<< + '.';
throw stream.str();
}
return value;
}
#endif
main.cpp
#include <iostream>
#include "CartesianPoint.h"
int main() {
try {
std::vector<CartesianPoint> points; // It's already empty
while( condition(s) ) {
// do work
}
} catch( std::string& str ) {
std::cout << str << std::endl;
return -1;
} catch( ... ) {
std::cout << "Caught some other or unknown exception." << std::endl;
return -1;
}
return 0;
}
EDIT - I made a change to the validateCoordinateValue I first changed it's name to just validate for several reasons:
1st: It is a private method to the function and it isn't exposed as part of its public interface.
2nd: It is shorter and easier to type as well as read.
3rd: When using it in the class just as validate() it is already self explanatory of what the function does. Compare the two:
myX = validateCoordinateValue( x );
myX = validate( x );
Then I also added in an overload of the function to accept pass by reference as well. The reference version does the work, the pass by value function just simply returns and calls the reference version.
This question probably only makes sense for people with knowledge on programming languages supporting closures. If you don't, please do not comment "why would you like to do this?": there are tons of legitimate reasons to do that.
It is common in functional languages to define local functions that capture the already defined local variables. In C++, that would look like (but of course is illegal):
#include <iostream>
using namespace std;
int main()
{
int x = 0;
int f() { return x + 1; }
cout << f() << endl; // would print 1
x = 2;
cout << f() << endl; // would print 3
}
To allow this, C++11 introduces lambda functions, so it is actually possible to do it in a rather nice way (though, not as nice as it generally is in functional languages ;-) ):
#include <iostream>
using namespace std;
int main()
{
int x = 0;
auto f = [&] () { return x + 1; };
cout << f() << endl; // actually compiles and prints 1
x = 2;
cout << f() << endl; // actually compiles and prints 3
}
My question is: now that it is possible to automatically capture free variables by reference for functions, wouldn't that be nice to be possible to do for locally defined structs? Ideally, I would love to be able to write:
int main()
{
int x = 0;
struct A
{
int y;
A(int y) : y(y) {}
int f() { return x + y; };
};
A a1(1);
A a2(2);
cout << a1.f() << endl; // would print 1
cout << a2.f() << endl; // would print 2
x = 2;
cout << a1.f() << endl; // would print 3
cout << a2.f() << endl; // would print 4
}
The only workaround I've found is to manually pass as argument to the constructor all the non-local (free) variables, which is a bit of a pain when there are plenty of them:
#include <iostream>
using namespace std;
int main()
{
int x = 0;
struct A
{
// meaningful members
int y;
int f() { return x + y; };
// free variables
int & x;
// Constructor
A(
// meaningful arguments
int y,
// capturing free variables
int & x
) : y(y), x(x) {}
};
A a1(1, x);
A a2(2, x);
cout << a1.f() << endl; // prints 1
cout << a2.f() << endl; // prints 2
x = 2;
cout << a1.f() << endl; // prints 3
cout << a2.f() << endl; // prints 4
}
Do you know of any other workaround that would avoid manually passing as argument all free variables, or do you know if these kind of "environment-aware" locally-defined structs are considered for future extensions of C++? (i.e., C++1y?)
What you ask for is not available, but you can get similar results by combining functions with a combination of lambdas and binders:
auto lambda = [](int i) { return x+i; };
auto a1 = std::bind(lambda,1);
auto a2 = std::bind(lambda,2);
Depending on the amount and shape of changes, you could invert the solution and have a struct that takes the lambda with the capture and then adds it's own logic.
I don't find this particularly beautiful, and I'm not entirely sure it's compliant, but neither g++ nor clang++ complains about this:
#include <iostream>
int main()
{
int x = 1;
auto l = [&](int p){
auto ll0 = [&, p]{ return p + x + 5; };
auto ll1 = [&, p]{ return p + x * 2; };
struct
{
decltype(ll0) l0;
decltype(ll1) l1;
} ret{ll0, ll1};
return ret;
};
std::cout << l(42).l0() << '\n';
auto lo = l(21);
std::cout << lo.l1() << '\n';
}
I think the creation of the unnamed struct could possibly be automated by a macro.
The lambda expressions of C++ are the capturing mechanism and inline object literals of a sort. Depending on your exact purpose, they may be more convenient than a local struct definition.
As a motivating example, consider the following:
// environment
int offset = 42;
struct local_type {
// capture environment 'by-hand'
int offset;
// purpose of the local type is to expose two overloads
int operator()(int x) const
{ return x + offset; }
double operator()(double x) const
{ return x + offset; }
} f { offset };
You can turn this on its head by doing:
int offset = 42;
auto f = make_overload([=](int x) { return offset + x; },
[=](double x) { return offset + x; });
The lambda expressions take care of capturing, the make_overload combinator takes care of building the desired object -- here, one that has an overloaded operator(). (It would be implemented best by making use of inheritance.)
This approach makes sense if you know that you'll (re)use make_overload from various places. For one-time, special uses there's no avoiding writing a specialty type, whether local or not.
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;
}