What's wrong with this constructor? - c++

class Ball
{
public:
int i,j,iplus,jplus;
Ball(int i , int j , int iplus , int jplus)
{ iplus=1;
jplus=1;
i=400;
j=300;
}
};
int main()
{
Ball toop(Ball);
}
I get the following error:
request for member ‘jplus’ in ‘toop’, which is of non-class type ‘Ball(Ball)’

Ball toop(Ball);
should be something like:
Ball toop(10,20,30,40);
Accidentally(as most users), you have created is called as the Most Vexing Parse in C++.
It does not create a object as you think it does, instead it declares a function which takes Ball as an input parameter and returns Ball.

Ball toop(Ball); //function declaration
It declares a function toop which takes one argument of type Ball, and returns Ball. It doesn't define an object.
I think you wanted to write something like this:
Ball toop(1,2,3,4); //object definition
Apart from that you should be using member-initialization-list in the constructor as:
Ball(int i , int j , int iplus , int jplus)
: i(i), j(j), iplus(iplus), jplus(jplus)
{ //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ its called member-initialization-list
}
Here, the syntax i(i) looks weird, but it means the other outer i is initialized with the inner i. The inner i is the constructor parameter-name, and the outer i is the member of the class, as shown below:
: i (i), j(j), iplus(iplus), jplus(jplus)
^ ^
| parameter-name
class-member-name
Similar explanation is for others as well : j(j), iplus(iplus), jplus(jplus)

Ball toop(Ball);
declares a function.
You didn't show the rest of your code, but it says
toop.jplus
somewhere else. That doesn't fly, because toop is a function pointer (non-class type). A function type doesn't support the member access operator (.) hence the error message.
Ball toop(1,2,3,4);
int y = toop.jplus;
would work. Although I'm mighty interested what you are trying to achieve in the constructor :)
I suggest:
class Ball
{
public:
int i,j,iplus,jplus;
Ball() : jplus(1), iplus(1), i(400), j(300)
{
}
};
int main()
{
Ball toop; // **not** toop()!
int test = toop.j; // 300
}

You forgot to post your full testcase. The code you posted is perfectly valid.
What your main presumably really looks like is:
int main() {
Ball toop(Ball);
toop.jplus = 2; // or something
}
Except when you tried to create toop, you actually just declared a function called toop that takes and returns objects of type Ball. I'm not quite sure why you've done that.
To use your constructor and create an object, use code that looks like this:
Ball toop(1,2,3,4);
And please, next time, post an actual testcase that reproduces the problem. You were lucky that:
the error message gave the issue away
I'm very good

Ball toop(Ball);
is wrong because you declared it with 4 parameters, so you should pass the four parameters. Like Your constructor is taking 4 integers as parameter so pass 4 integer values
Like
Ball toop(0,0,0,0);
Or
int x=0;
Ball toop(x,x,x,x);

Related

c++ Error when Testing library

I am creating an Arduino library which takes two constructors for a personal project of mine, but for some reason I keep getting an error which is specific to types, first let me show you how the structure goes. so here is my files:
this is the header file:
#ifndef iGA_H
#define iGA_H
class iGA {
public:
getParameters(int soundA[], int soundB[], int parentId[]);
private:
int _soundA[];
int _soundB[];
int _parentId[];
}
the cpp file:
#include <iGA.h>
iGA::getParameters(int soundA[], int soundB[], int parentId[])
{
_soundA = soundA;
_soundB = soundB;
_parentId = parentId;
}
And this is how im pretty much calling the constructor in the sketch, within the setup() function:
#include <iGA>
iGA iga;
void setup() {
iga.getParameters(r, r1 , r2);
}
and here is the error:
In file included from /home/bargros/Dropbox/iGA__NewBild/iGA__NewBild.ino:34:0:/home/bargros/Arduino/libraries/iGA/iGA.h:10:58: error: ISO C++ forbids declaration of 'getParameters' with no type [-fpermissive]getParameters(int soundA[], int soundB[], int parentId[]);
I know the error has something to do with argument types or maybe im calling the constructor wrongly but I also tried calling it like this:
iGA iga = getParameters(etc,etc,etc);
im relatively new to c++ and im a little clueless as to what this error is telling me. Does anyone have any sort of idea of why this happens?
I believe two issues:
Issue 1: Your function should return something right? you may want to set it as void if it just meant to assign the parameters to the private members (it is a setter and not a get in your case). Add void in the proper locations both inside the class and when you write its definition.
Issue 2: I think that you can't send an array[] as a parameter. And I assume that you already know the size. You need, instead, to send a pointer that points to the first element of the array along with the size of the whole array. Then, once you receive the parameters, for every private member, you create a new array with the size received (or just fill the private member directly) and fill the values by iterating the received array using the pointer received.
Edit: I just checked and passing int array[] should be fine. So fixing issue one will fix your problem. See here for further documentation.
In C++ you have to be explicit that a function doesn't return anything, which you do by saying it returns void:
getParameters(int soundA[], int soundB[], int parentId[]);
needs to be
void getParameters(int soundA[], int soundB[], int parentId[]);
and
iGA::getParameters(int soundA[], int soundB[], int parentId[])
needs to be
void iGA::getParameters(int soundA[], int soundB[], int parentId[])

Class method being called in main, changes don't persist outside class method?

Basically, I have two classes, Peg and Disk. (It's a Towers of Hanoi program) The files I have are Disk.h, Disk.cpp, Peg.h, Peg.cpp, and main.cpp. Not sure if that matters. Here's the disk class from Disk.h
#include <vector>
#include "gwindow.h"
#ifndef DISK_H
#define DISK_H
class Disk
{
private:
int xCoord; //x and y coords are for drawing in a gwindow
int yCoord;
int mHeight;
int mWidth;
COLOR mColor;
int mName; //helps me keep track of which is which
public:
Disk(); //default constructor
Disk(int x, int y, int heightIn, int widthIn, COLOR colorIn);
void setXY(int x, int y); //this is the one I'm having trouble with
int getHeight();
int getWidth();
int getX();
int getY();
COLOR getColor();
std::string diskColor();
void draw(GWindow &gw);
void nameDisk(int name); //yet this one is working?
int getName();
};
#endif
However, I'm having trouble with the setXY function. When I call it from main, it calls the function properly, changes the variable inside the scope of setXY, but the value doesn't persist outside the function. However, nameDisk works fine and is basically the same thing, except it is changing mName instead of xCoord and yCoord. Here is setXY:
void Disk::setXY(int x, int y)
{
xCoord = x;
yCoord= y;
}
and here is how I call it from main:
pegVec[2].getDisks()[0].setXY(690, 200);
I know this looks crazy, but basically pegVec is a vector of 3 peg objects. Each peg object has a function, getDisks(), which returns a vector of all the disks on that peg currently. So the line above is trying to perform setXY on the first peg on peg 2. Sorry if that's unclear, but I've tried making a new disk object and calling it on that and that didn't work either.
Here is getDisks, if it matters:
std::vector<Disk> Peg::getDisks()
{
return disksOn;
}
and disksOn is just a member variable of Peg:
std::vector<Disk> disksOn;
I think it might be a problem with how getDisks() works. I'm a noob, but I'm guessing that returning the vector disksOn makes a "copy" of it, kind of, which is what I am altering with my setXY function but which is not the same as the actual disksOn vector associated with the Peg object? I don't know if that makes sense.
What I've tried so far:
Making xCoord and yCoord public variables and updating them manually instead of making a setter function. This did not work.
I printed out the x and y values at every step. Inside setXY, the values were updated successfully, but when the function ended they went back to how they were.
I tried some mess with the const keyword, but I don't understand it and couldn't even get it to run.
Passing everything by reference/value
Making a new function in main which accepted a Disk vector as input, and using getDisks as input to that function. Didn't work, same problems.
Tested my other setter function, nameDisk, which works fine. It's essentially the same as setXY, which is why I think the problem is with getDisks.
Using pointers at various points (heh) throughout, but I wasn't sure the best way to do that. I was messing with it last night so I don't remember 100% but I think I tried to have getDisks return a pointer instead of the vector, and I don't think that worked, but it's more likely a problem with my syntax and how I used the pointer. I think that might work but I don't know how to shake it.
Help?
You're on the right track - somehow you're looking at a different objects than what you think you are. Using references is a good solution, but you may not have got the right one ;-)
Try:
// Return reference to the disks on the peg.
std::vector<Disk>& Peg::getDisks()
{
return disksOn;
}
The issue is that
std::vector<Disk> getDisks() { return disksOn; }
returns a completely new and separate temporary copy of disksOn rather than a reference to the original. So you're modifying a temporary copy which gets discarded at the end of the statement.
You need to use
std::vector<Disk> &getDisks() { return disksOn; } in order to return a reference to disksOn.
Although if you are going to return a reference to the vector member object you might as well make the object directly accessible as public because anyone can manipulate the vector at this point and get rid of the getDisks() function as it serves no purpose in terms of access protection.
Better design would be to give access to individual disks:
Disk &getDisk(int index) {
return disksOn[index];
}
const Disk &getDisk(int index) const {
return disksOn[index];
}
The idea behind not giving direct access to the vector is that you can later change the underlying container type if needed without changing the code outside of the Peg class.
The second version (const) is necessary for accessing const Disks of const Peg objects.

How to access data member of a class member function in main function?

XX.HEADER
class ABC
{
public:
ABC(); // constructor
int XYZ(int );
int AA;
int m
}
XX.CPP
Mat ABC::XYZ(int c)
{
AA = lambda;
return m;
}
MAIN.CPP
int main()
{
ABC myObject;
int labda = myObject.AA;
}
I want value of AA to be used in main function.
Suppose there is a header file with class definition and member function definition along with some public data members say
AA.
Now in the cpp file for the header file with contain complete description of the header file along with function definition within the class. The data member
AA
contains some value within the member function. Now I want to use this data member
AA
in the main function. How can I do that. Right now I have just intialiazed in public: int AA and in function it is giving some integer value which is getting stored. Now I want to use this AA in main function.
Post a smallest example of your problem using actual C++. But from that... i would not even call it pseudo-code, your problem might be that you need to call
myObject.XYZ(someInteger);
before you inspect myObject.AA.
Also, when you post some actual code, also state what exactly goes wrong. Is there a runtime error, is the value just unexpected, does your computer explode?

std::vector::push_back fails to add data to my vector

I have these two pieces of code that are messing up without throwing any errors:
The first piece is from a custom class which I am trying to push into an array.
class idRect {
public:
sf::FloatRect rect;
int id;
idRect(int _id, sf::FloatRect _rect) : id(_id), rect(_rect) {}
};
The second piece is where the function gets called.
if((deltaX + deltaY) < 500) { //Taxi distance calculation
cout << endl << "Passed check" << endl;
gloAreas.push_back(idRect(id, entity.getGlobalBounds()));
}
gloAreas is a globally defined vector which contains idRect objects.
As said earlier I have observed from the console that "Passed check" outputs and that the size of my vector doesn't increase EDIT: globally.
Edit: The error also seems rather random and only happens for 1 in 6 instances of the objects calling the push_back functions.
I'm using SFML for the sf::FloatRect which is basically just a vector of 4 floats. getGlobalBounds() is another function from SFML that returns the bounding rectangle of a sprite in sf::FloatRect format.
Any ideas of what is going wrong?
Sincerely,
BarrensZeppelin
EDIT 2:
The error seems to have erupted due to a mix between my own incompetence and std::multiset's sorting, maybe I'll come back for that in another thread ^^ (With a sscce ofc)
Thank you guys for you time and help.
If gloAreas is defined as static, it won't be a true global. It will have global scope, but a copy of it will be created for each translation unit.
For a global, you need to declare it with extern and define it in a single implementation file.
Disclaimer: answer is just a guess, my crystal ball might be off today...
My crystal ball answer: You have redefined gloAreas in an interior scope, like this:
vector<idRect> gloAreas; // defines global
void F( vector<idRect> gloAreas ) // defines local instance
{
gloAreas.push_back(); // affects local instance
return; // destroys local instance
}
int main() {
F(gloAreas); // Copies global instance to parameter
// global remains unchanged.
}

I'm messing up my inheritance

So I've got a Piece class supposed to represent pieces on a board, from which I plan to have two other classes inheriting. I've gotten a lot of problems in doing so, however; here is the relevant code so far.
///
/// PIECE CLASS HERE
/// this is an abstract class from which Barrier and Pawn inherit.
class Piece
{
public:
Piece(Space* start);
sf::Shape m_Circle;
protected:
int m_X;
int m_Y;
int m_radius;
Space* CurrentSpace;
};
Piece::Piece(Space* start):
m_X(start->GetX()),
m_Y(start->GetY()),
m_radius(14),
CurrentSpace(start)
{}
///
/// BARRIER CLASS HERE
/// these are the white stones that block a player's path
class Barrier : public Piece
{
public:
Barrier(Space* initial);
void Move(Space* target, bool isCapturing);
};
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
void Barrier::Move(Space* target, bool isCapturing)
{
int xChange = abs(target->GetX() - m_X);
int yChange = abs(target->GetY() - m_Y);
m_Circle.Move((float)xChange, (float)yChange);
CurrentSpace.ToggleOccupied();
if(!isCapturing)
{
(*target).ToggleOccupied();
}
CurrentSpace = target;
}
I'm getting loads of errors I don't understand, in particular:
no matching function for call to Piece::Piece()
declaration of 'Piece initial' shadows a parameter
no matching function for call to 'Barrier::Move(Piece&)'
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
Being new to C++, I don't understand what's going wrong with any of this. I tried to build my code analogous to the code I found in the book I used to learn C++, but apparently I've overlooked some subtlety. All the functions that I try to call seem to exist in the appropriate places, and I define them with the same values as in their prototype, I think.
The first error is caused by this:
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
Needs to look like:
Barrier::Barrier(Space* initial) : Piece(initial)
{
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
The base class' constructor runs before your constructor (no matter what) -- you need to pass arguments to it if it requires arguments in the initialization list.
I'm not sure about the other errors because I don't know which lines they're occurring on.
The parenthesis in the line
Piece(initial);
are ignored by the compiler. You are declaring a variable with the same name as the parameter:
Piece initial;
To initialize the Piece base object with initial, you have to use the member initializer list:
Barrier::Barrier(Space* initial) : Piece(initial)
Also, the Move function expects two arguments, but you're only passing one. You forgot the boolean.
Good answers, all. Plus that final daunting line
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
is being caused from
CurrentSpace.ToggleOccupied();
you have declared CurrentSpace to be a pointer, so this should be
CurrentSpace->ToggleOccupied();
If you want to initialize the super class, you should do it like this:
Barrier(Space* initial):
Piece(initial) {
...
}
If you don't explicitly initialize the base type, the compiler will try to initialize it by calling a constructor with an empty argument list, like this:
Barrier(Space* initial):
Piece() {
...
}
But since you don't define a constructor for Piece that takes zero arguments, you get the compiler error you described.