Non static members in C++ - c++

error C2648: 'stack::Y' : use of member as default parameter
requires static member
error C2648: 'stack::X' : use of member as default parameter
requires static member
IntelliSense: a nonstatic member reference must be relative to a
specific object
IntelliSense: a nonstatic member reference must be relative to a
specific object
Please, help to fix it
class stack{
node *head, *tail;
int maze[10][10], X, Y, _X, _Y;
public:
stack():head(0), tail(0){};
~stack();
void load();
void makelist(int = X, int = Y); //error is here
void push(int, int);
void pop();
void print();
};
void stack::load(){
ifstream fin("maze.txt");
fin >> X >> Y >> _X >> _Y;
cout << "Loaded matrix:" << endl << endl;
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10; j++){
fin >> maze[i][j];
if (i == X && j == Y)
cout << "S ";
else if (i == _X && j == _Y)
cout << "F ";
else
cout << maze[i][j] << " ";
}
cout << endl;
}
}
void stack::makelist(int x, int y)
{
if (x == _X && y == _Y)
{
push(x, y);
print();
pop();
return;
}
if (x > 0) if (maze[x - 1][y] == 0) { maze[x][y] = 1; push(x, y); makelist(x - 1, y); pop(); maze[x][y] = 0; }
if (x < 9) if (maze[x + 1][y] == 0) { maze[x][y] = 1; push(x, y); makelist(x + 1, y); pop(); maze[x][y] = 0; }
if (y > 0) if (maze[x][y - 1] == 0) { maze[x][y] = 1; push(x, y); makelist(x, y - 1); pop(); maze[x][y] = 0; }
if (y < 9) if (maze[x][y + 1] == 0) { maze[x][y] = 1; push(x, y); makelist(x, y + 1); pop(); maze[x][y] = 0; }
}
<...>
int main()
{
stack obj;
obj.load();
obj.makelist();
system("pause");
return 0;
}

(this is a correction to my old answer, which was incorrect)
It seems that you want to use a non-static member as a default value for a parameter, and the compiler tells you this is impossible. You can use an overload as a workaround:
class stack{
node *head, *tail;
int maze[10][10], X, Y, _X, _Y;
public:
void makelist() {makelist(X, Y);} // I added this overload to do what you want
void makelist(int x, int x);
...
};
Some people would say overloading is better than using default values, because you probably don't want to support calling makelist with 1 parameter, only with 0 or 2 parameters (or, if you actually want this, you can add another overload, with 1 parameter).

You have a spurious "=" character in your code; replace your line with error with the following:
void makelist(int X, int Y);
The "=" character makes it look like the declaration has default parameters whose values are X and Y, which is totally not what you intended to do.
In addition, it is customary to have the same parameter names in declaration and definition:
void makelist(int x, int x); // declaration - I replaced X by x, Y by y
...
void stack::makelist(int x, int y) // definition - has lowercase names, which are good
{
...
}

Get rid of those = signs in the function declaration:
void makelist(int x, int y);
so it's just like the definition:
void stack::makelist(int x, int y)
{

Presuming you meant to use default values
void makelist(int x_ = X, int y_ = Y); //error is here
This is not allowed as the default values must be compiletime constants or compiletime addressable, which members of a not instantiated class are not.
The compiler needs an address be able to generate the code.
You can overload the function
void makelist(int x_, int y_);
void makelist() { makelist(X,Y); }
And so get nearly the same behaviour as you asked.
If you have a problem with _X & _Y then its because the compiler reserves _??? for itself or libraries.

Related

How to declare vector of object in c++?

I receive the following error on declaring a vector of Point in the code shown (see reference to class template instantiation std::vector<Point,std::allocator<Point>> being compiled):
Severity Code Description Project File Line Suppression State
Error C2558 class 'Point': no copy constructor available or copy
constructor is declared 'explicit' AI assignment 1 C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 671
#include <iostream>
#include<vector>
using namespace std;
int dx, dy, sx, sy;
class Point
{
public:
int x;
int y;
float g;
float h;
Point()
{}
Point(int s, int d)
{
x = s;
y = d;
h = pow(pow(x - dx, 2) + pow(y - dy, 2), 1 / 2);
}
Point(Point &p)
{
x = p.x;
y = p.y;
g = p.g;
h = p.h;
}
bool operator == (Point p)
{
if (p.x == x && p.y == y)
return true;
else
return false;
}
};
class RoutePlaner
{
vector<vector<char>>grid;
int mapsize;
Point start;
Point destination;
int no_of_obstacles;
vector<Point> obstacles;
void generate_random_obstacles(int num)
{
for (int i = 0; i < num; i++)
{
int k = rand() % mapsize;
int j = rand() % mapsize;
Point p(i, j);
grid[j][k] = 'X';
obstacles.push_back(p);
}
}
public:
RoutePlaner(int m, Point s, Point d, int no)
{
mapsize = m;
start = s;
destination = d;
no_of_obstacles = no;
vector<char> vec(mapsize, '.');
for (int i = 0; i < mapsize; i++)
{
grid.push_back(vec);
}
//Setting start and destination
grid[start.x][start.y] = 'S';
grid[destination.x][destination.y] = 'D';
// setting obstacles
generate_random_obstacles(no_of_obstacles);
}
};
int main()
{
}
How should I declare a vector of class objects? How do I resolve the error?
You need your copy constructor for the Point class to conform to what std::vector (and many other aspects of the STL and C++ language) expects: that means its argument should be a const reference:
Point(const Point& p)
{
x = p.x;
y = p.y;
g = p.g;
h = p.h;
}
Although, in your case, as pointed out in the comment by M.M, the compiler-generated copy constructor will do exactly the same job as yours, so you can just omit your 'explicit' version. Furthermore, if you do declare your own copy constructor, you should also declare a destructor and an assignment operator, in order to follow to "Rule of Three." (Or you can 'meet halfway' by explicitly declaring the default copy constructor: Point(const Point& p) = default;.)
Note, also, that you can simplify your operator == function: whenever you have code of the form, if (x) return true; else return false; you should consider using just return (x);, like this:
bool operator == (Point p) {
return (p.x == x && p.y == y);
}

c++ Assigning reference variable in an if statement

How can I assign a reference variable based on an if statement?
For example, the following example doesn't work because "smaller" doesn't have scope outside of the if-statement.
int x = 1;
int y = 2;
if(x < y)
{
int & smaller = x;
}
else if (x > y)
{
int & smaller = y;
}
/* error: smaller undefined */
However, the following example also doesn't work because references must be assigned to objects immediately.
int x = 1;
int y = 2;
int & smaller; /* error: requires an initializer */
if(x < y)
{
smaller = x;
}
else if (x > y)
{
smaller = y;
}
I could achieve the reference assignment with a ternary-if statement, but what if I can't use that?
use a function:
int &foo(int &x, int &y) {
if(x < y)
{
return x;
}
else if (x > y)
{
return y;
} else {
// what do you expect to happen here?
return x;
}
}
int main() {
int x = 1;
int y = 2;
int & smaller = foo(x, y); /* should work now */
}
Note, in your case, I would even expect foo to return a const int& as it would seem strange to modify the value identified as smaller, but as you did not use it const in you question, i keep it like this.
EDIT:
With C++ 11 and above, you can use a lambda that you call on the go:
int main() {
int x = 1;
int y = 2;
const int & smaller = [&] {
if(x < y)
{
return x;
}
else if (x > y)
{
return y;
} else {
// what do you expect to happen here?
return x;
}
}(); /* should work now */
}

Forward declaration of struct with constexpr constructor

I would like to add global instances of a struct class to my program that server special meaning. A MWE that works is
// Example program
#include <iostream>
constexpr int x_max = 3;
constexpr int y_max = 4;
typedef struct Position {
constexpr Position(int x, int y) : x(x), y(y) {};
int x;
int y;
inline bool operator!=(const Position &rhs) const {
return (x != rhs.x || y != rhs.y);
}
inline bool inside_grid(const Position &empty) const {
return (x >= 0 && x < x_max && y >= 0 && y < y_max && *this != empty);
}
} Position;
constexpr Position empty = Position(1,1);
int main()
{
Position p1 = Position(2,3);
Position p2 = Position(1,1);
std::cout << "p1.inside_grid(empty) = " << p1.inside_grid(empty) << " and p2.inside_grid(empty) = " << p2.inside_grid(empty) << std::endl;
}
The global constant empty would have to be passed to every call of method inside_grid which made me think if I could declare the global at the beginning of the program and modify the inside_grid method to not take any parameters like so:
// Example program
#include <iostream>
struct Position;
constexpr Position empty = Point(1, 1);
constexpr int x_max = 3;
constexpr int y_max = 4;
typedef struct Position {
constexpr Position(int x, int y) : x(x), y(y) {};
int x;
int y;
inline bool operator!=(const Position &rhs) const {
return (x != rhs.x || y != rhs.y);
}
inline bool inside_grid() const {
return (x >= 0 && x < x_max && y >= 0 && y < y_max && *this != empty);
}
} Position;
int main()
{
Position p1 = Position(2,3);
Position p2 = Position(1,1);
std::cout << "p1.inside_grid() = " << p1.inside_grid() << " and p2.inside_grid() = " << p2.inside_grid() << std::endl;
}
The problem is that this won't compile due to errors that I cannot really understand:
error: variable 'constexpr const Position empty' has initializer but incomplete type
error: invalid use of incomplete type 'struct Position'
Can this problem be resolved?
You can forward declare your inside_grid() method and define it later, after empty is created:
// Example program
#include <iostream>
struct Position;
constexpr int x_max = 3;
constexpr int y_max = 4;
typedef struct Position {
constexpr Position(int x, int y) : x(x), y(y) {};
int x;
int y;
inline bool operator!=(const Position &rhs) const {
return (x != rhs.x || y != rhs.y);
}
bool inside_grid() const;
} Position;
constexpr Position empty = Position(1, 1);
inline bool Position::inside_grid() const {
return (x >= 0 && x < x_max && y >= 0 && y < y_max && *this != empty);
}
int main()
{
Position p1 = Position(2,3);
Position p2 = Position(1,1);
std::cout << "p1.inside_grid() = " << p1.inside_grid() << " and p2.inside_grid() = " << p2.inside_grid() << std::endl;
}

Unable to change private variables using member functions

#include <iostream>
#include <string>
using namespace std;
struct Point {
private:
int xCord,yCord;
public:
void setX(int x);
void setY(int y);
int getX();
int getY();
int rotate(int x, int y, Point p1);
int moveHorizontally(int x, int a, int b);
int moveVertically(int y, int a, int b);
};
int main() {
Point p1;
p1.setX(1); //sets X
p1.setY(2); //sets Y
cout << p1.getX() << ", " << p1.getY() << endl; //prints current value of X & Y
p1.rotate(p1.getX(), p1.getY(), p1);
cout << p1.getX() << ", " << p1.getY() << endl;
return 0;
}
void Point::setX(int newX) {
xCord = newX;
}
void Point::setY(int newY) {
yCord = newY;
}
int Point::getY() { //This will just return the y Cord.
return yCord;
}
int Point::getX() { //This will just return the x Cord.
return xCord;
}
int Point::moveHorizontally(int x, int tempX, int tempY) {
//Move the point to the right if positive.
//Move the point to the left if negative.
int newX = tempX + (x);
return newX;
}
int Point::moveVertically(int y, int tempX, int tempY) {
//Move the point up if positive.
//Move the point down if negative.
int newY = tempY + (y);
return newY;
}
int Point::rotate(int tempX, int tempY, Point p1){
//(1,2) -->> (-2,1)
int tempX_DNC = tempX;
int tempY_DNC = tempY;
int quadrant;
if((tempX > 0) && (tempY > 0)) { //Quadrant 1: x(positive), y(positive) Then rotates to Quad 2
quadrant = 1;
tempX = -(tempY);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY > 0)) { //Quadrant 2: x(negative), y(positive) Then rotates to Quad 3
quadrant = 2;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY < 0)) { //Quadrant 3: x(negative), y(negative) Then rotates to Quad 4
quadrant = 3;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX > 0) && (tempY < 0)) { //Quadrant 4: x(positive), y(negative) Then rotates to Quad 1
quadrant = 4;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else {
quadrant = 0;
}
//This will rotate the points 90* to the left.
//(1,2) will then become (-2,1)
//I could have if in quadrant1, all are positive, if in quadrant 2 the x would be negative and y would be positive
//If in quadrant 3 the x and y will both be negative, if in quadrant 4 the x would be positive and the y would be negative
cout << tempX << ", " << tempY << endl;
p1.setX(tempX);
p1.setY(tempY);
cout <<"x is: " <<p1.getX() <<endl;
cout <<"Y is: " <<p1.getY() <<endl;
}
Code is above.
So I am creating a class Point. Point has 2 private variables xCord, yCord. I want to call the rotate function and have that be able to modify the xCord, yCord but it does not. I am not sure why. I tried passing the Point p1 to the function and to see if that would fix the issue but it did not, I also tried without passing the Point p1 and just having Point p1 inside the function definition.
p1.setX(VARIABLE);
works when it is in main(). but not when I call p1.setX(VARIABLE) inside another member function.
You are passing a copy of p1 to the rotate function. Only this copy is modified.
You pass the point by value:
int rotate(int x, int y, Point p1);
^^--------pass-by-value
ie. the p1 inside the function is a copy of p1 in main that gets deleted once the function returns. If you want to change the point that is passed as parameter inside the function then pass it by reference:
int rotate(int x, int y, Point& p1);
^^--------pass-by-reference
PS: ... However, as rotate is a member function of Point you should probably rather rotate the instance on which you are calling it, change its signature to
int rotate(int x, int y);
and instead of changing the coordinates of some point passed as parameter do this:
this->setX(tempX); // this-> not really necessary, just added for clarity
this->setY(tempY);
Alternatively you keep it as is and pass the point that is supposed to be rotated as parameter, but then you should consider making the method static.
PPS: If you want to change it to pass-by-reference, you have to change the signature in the class declaration to:
int rotate(int x, int y, Point& p1);
and the definition you have to change to:
int Point::rotate(int tempX, int tempY, Point& p1) { /*...*/ }
void point::rotate() {
xcord = ycord;
ycord = xcord;
}
is all you need for basic rotation

How can I use a class object in another function? c++

How can i use the x and y values of lastLoc object in another function like in the following code. I get no errors but when i print the values of lastLoc in the getPosLoc function I get a long number(possibly address):
class solveMaze {
private:
maze maze;
mouse m;
stack<coords> coordStack;
int x;
int y;
int posLocCount = 0;
coords lastLoc;
};
solveMaze::solveMaze() {
x = m.x;
y = m.y;
coords c(x, y);
coords lastLoc(c.x, c.y);
coordStack.push(c);
}
void solveMaze::getPosLoc() {
if((mazeLayout[x][y-1] == 0) && (x != lastLoc.x) && (y-1 != lastLoc.y)) {
posLocCount++;
putUp();
}
this is the coords.h removed irrelevant functions to shorten the code:
class coords {
public:
coords(){};
coords(int, int);
int x;
int y;
friend ostream &operator<<(ostream &output, const coords &c);
bool operator==(coords);
void operator=(const coords &b);
};
coords::coords(int a, int b) {
x = a;
y = b;
}
this is mouse.h:
class mouse {
private:
maze maze;
public:
mouse();
int x;
int y;
};
mouse::mouse() {
for (int i=0; i<12; i++) {
for (int j=0; j<29; j++) {
if (mazeLayout[i][j] == 8){
x = j;
y = i;
}
}
}
}
There are a couple of evident problems:
coords lastLoc(c.x, c.y);
This statement declares and initialize a local variable named lastLoc... it is not referring to the member lastLoc. For that the code needs to be
lastLoc = coords(c.x, c.y);
x = m.x; and y = m.y;
These statements use m that has not been explicitly initialized, how is that class defined?
You should make getters and setters for x and y, because it's better practise. But if you want refer to coord's x or y. You should write:
lastLoc->x