Member not declared in scope? - c++

So I'm trying my hand at some C++ after finishing up an introductory book, and I've become stuck. I've made a vector of objects that each have an SFML circle object as a member, and I want main() to go and draw these circles. The vector is called theBoard, but when I try to access it, I get the following error messages:
error: request for member 'theBoard' in 'GameBoard', which is of non-class type 'Board*'
error: 'theBoard' was not declared in this scope
I'm new to this (came from two years of Python), so I'm sure I made a mistake somewhere. Here is the relevant code for the board creation:
class Board
{
public:
//These are the member functions.
Board();
~Board();
vector<Space*> CreateBoard();
//This will be the game board.
vector<Space*> theBoard;
//These clusters represent the waiting areas for pieces not yet in the game.
vector<Space*> Cluster1;
vector<Space*> Cluster2;
vector<Space*> Cluster3;
private:
//These integers represent the number of spaces on each row, starting at the top (which is row [0])
vector<int> RowNums;
};
Board::Board()
{
//Fill in RowNums with the right values.
RowNums.push_back(1);
RowNums.push_back(17);
RowNums.push_back(2);
RowNums.push_back(17);
RowNums.push_back(1);
RowNums.push_back(1);
RowNums.push_back(5);
RowNums.push_back(2);
RowNums.push_back(7);
RowNums.push_back(2);
RowNums.push_back(11);
RowNums.push_back(3);
RowNums.push_back(17);
RowNums.push_back(4);
RowNums.push_back(17);
//Then, create the board.
theBoard = CreateBoard();
}
CreateBoard() is a very, very long function that returns a vector of pointers to Space objects. I doubt there's a problem here, as the only error message I get crops up when I try to access the circle members of Space objects in main(). It seems to me as though I have declared theBoard in the relevant scope, that is, as a data member of the Board class.
My main() function, in case it's important:
int main()
{
//This sets up the display window.
sf::RenderWindow App(sf::VideoMode(1200, 900, 32), "Malefiz");
//This creates the board on the heap, and a pointer to it.
Board* GameBoard = new Board();
cout << "Board made.";
//This is the game loop.
while(App.IsOpened())
{
//This is used to poll events.
sf::Event Event;
while(App.GetEvent(Event))
{
//This closes the window.
if(Event.Type == sf::Event::Closed)
{
App.Close();
}
}
//This gets the time since the last frame.
//float ElapsedTime = App.GetFrameTime();
//This fills the window with black.
App.Clear(sf::Color(200, 200, 125));
//This draws the places into the window.
for(int i = 0; i < GameBoard.theBoard.size(); ++i)
{
App.Draw(GameBoard.*theBoard[i].m_Circle);
}
//This displays the window.
App.Display();
}
return EXIT_SUCCESS;
}

In your main() function, GameBoard is a Board *, not a Board. So to access members, you need to use -> instead of .. e.g.:
GameBoard->theBoard.size()
[Some people (I am one of them) like to name their pointer variables with a leading p or ptr prefix, in order to make this kind of irritation explicitly clear.]

GameBoard is a pointer to a Board object, and thus you need to use the "->" operator instead of the "." operator to access any of its member variables or methods.

The error is quite explicit if you read it carefully:
error: request for member 'theBoard' in 'GameBoard', which is of non-class type 'Board*'
error: 'theBoard' was not declared in this scope
The first line is telling you that you have a pointer to a Board object and you are trying to access a member directly. That is:
Board *p = ...
p.theBoard; // Error, should be p->theBoard, as p is a pointer
Also note that GameBoard.*theBoard[i].m_Circle might not be what you want, you probably want (I am guessing as there are important bits missing) something like GameBoard->theBoard[i]->m_Circle.

GameBoard is a pointer, so the syntax should be this:
for(int i = 0; i < GameBoard->theBoard.size(); ++i)
{
App.Draw((GameBoard->theBoard[i])->m_Circle);
}
Since elements of theBoard also are pointer, so I used the pointer notation when accessing m_Circle.

Related

C++ identifiers are undefined despite using said identifiers earlier in the function

I'm currently trying to make an enemy in a game. The Enemy is meant to move towards the player using the player position (x and y coordinate) and comparing it to the enemy's coordinates. however I seem to be having problems with the identifiers.
void DinoEnemy::Update()
{
DinoEnemy GetPosition(int& dinox, int& dinoy); ///calling a function that should return dinox and diny
m_AnimatedSprite.SetCurrentAnimation(E_DinoState_Hatching);
GameStateManager* pGameStateManager = C_SysContext::Get<GameStateManager>();
GameState* pCurrentGameState = pGameStateManager->GetCurrentGameState();
GameObject* PlayerPos = pCurrentGameState->GetPlayer();
if (PlayerPos)
{
int playerposX = 0;
int playerposY = 0;
PlayerPos->GetPosition(playerposX, playerposY);
}
if (dinox << playerposX) ///Here is where the error is.
{
dinox++;
}
}
dinox and playerposX are undeclared in the final if statement
Thanks in advance ;u;
That's not how you call a function
You have
DinoEnemy GetPosition(int& dinox, int& dinoy);
But that's no function call as your comment suggests, but a function declaration. You meant to declare two variables, then call the function (as you did later on in your code, so why do it wrong here?):
int dinox;
int dinoy;
GetPosition(dinox, dinoy);
Beware: If GetPosition reads from dinox and dinoy you must intialize the values, but it seems like it only writes them.
The scope of playerposX is wrong
The variables playerposX and playerposY are only visible inside the if-block, simply declare them outside of it:
int playerposX = 0;
int playerposY = 0;
if (PlayerPos)
{
PlayerPos->GetPosition(playerposX, playerposY);
}
There should probably be an else that handles the case when PlayerPos == nullptr. After all it doesn't make sense to compare the players position to something if the player doesn't have any position.
Little typo
if (dinox << playerposX)
Here you probably don't want a bitshift (<<) but rather a smaller-than-comparison (<).
There will be an issue with the scope of playerposX. Since it is declared inside the if block, it gets out of scope outside of the if block.
Additionally, in case PlayerPos cannot be translated to true, e.g., if it is NULL, playerposX will never be declared at all.
You may want to declare playerposX outside of the if block. Or add the second if block within the scope of the first.
In other words
if (PlayerPos)
{
int playerposX = 0;
int playerposY = 0;
PlayerPos->GetPosition(playerposX, playerposY);
if (dinox << playerposX)
{
dinox++;
}
}

Undefined reference to scene_render

Here is the following main function or my program
void scene_render(const struct Scene *s);
int main(void) { //leave main as is
struct Scene myScene;
scene_init(&myScene);
int keep_going = 1;
while (keep_going == 1) {
cons_clear_screen(); //clear off-screen display buffer
scene_render(&myScene); //render the scene to display buffer
cons_update(); //copy the display buffer to the display
cons_sleep_ms(ANIMATION_DELAY); //pause
scene_update(&myScene); //update the scene
int key = cons_get_keypress(); //see if the user has pressed a key
if (key != -1) {
keep_going = 0;
}
}
return 0;
}
void scene_render(Scene *s)
{
cons_clear_screen();
for(int i=0; i<NUM_PARTICLES; i++)
{
particle_render(&s->parts[i]);
}
}
When I run the makefile command on Cygwin, it passes the errors and starts compiling, but hits an error when it hits scene_render(&myScene);. It says that a reference to it is undefined. It refers to a variable in a function that is a const struct, while all other instances where &myScene is called are merely structs. Any idea what the issue may be? This lab is mostly about using pointers, if that helps.
The program (with assistance from external functions) should generate and throw randomly colored pixels around the command window, bouncing them back to keep them in the screen. Deleting the issue causes the program to compile successfully, but then loads a blank window that seems to do nothing.
Problem
With
void scene_render(const struct Scene *s);
you promise scene_render takes a const struct Scene as a parameter. By the way, you can discard the use of struct here. C++ knows Scene is a struct.
But the function that is defined is
void scene_render(Scene *s)
which takes a plain old, non-const Scene, so when the linker goes looking for a function that matches the promise it does not find one.
Solution
Change
void scene_render(Scene *s)
to
void scene_render(const Scene *s)
to keep the promise. But make certain that const-correctness is maintained throughout.

C++ STD Vector push_back doesn't seem to work

I'm making a game with SDL that used libconfig to read some settings from a file. The problem is that I made a class called ClipList that contains a std::vector<SDL_Rect> to store the settings but when trying to add SDL_Rect objects to the vector, for some reason push_back does nothing and I end up with an empty vector.
This is the class:
class ClipList
{
public:
ClipList();
ClipList(int);
virtual ~ClipList();
void addClip(int,int,int,int);
void getClip(int,SDL_Rect*);
int getLength();
protected:
private:
std::vector<SDL_Rect> clips;
};
ClipList::ClipList(int l)
{
clips.reserve(l);
}
void ClipList::addClip(int x,int y,int w,int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
clips.push_back(rect);
}
void ClipList::getClip(int i,SDL_Rect* rect){
rect = &(clips.at(i));
}
int ClipList::getLength(){
return clips.size();
}
And this is the function where I initialize the ClipList object. This function gets called from main.
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){
const Setting& root = placlips->getRoot();
int x,y,w,h;
try{
Setting& clipsett = root["clips"];
int cliplen = clipsett.getLength();
clips = new ClipList(cliplen);
flipclips = new ClipList(cliplen);
for(int i=0;i<cliplen;i++){
const Setting& c = clipsett[i];
if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){
continue;
}
clips->addClip(x,y,w,h);
}
}catch(const SettingNotFoundException &nfex){
cerr << "Setting not found at" << nfex.getPath() << endl;
}
}
Regardless of whether the ClipList objects get initialized in main or set_clips, clips.push_back(rect) doesn't work. The capacity of the vector changes but no object gets stored so I end up with a segfault if I try to do anything else with the vector, even checking if the vector is empty or not.
I am going to guess, the signature of the function
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips);
is the culprit. You are allocating memory for clips and flipclips in this function but since the pointers are passed by value, the calling function does not see the allocated memory.
If you change the function signature to:
void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips);
your problems should go away.
clips.push_back(rect) is working fine. Your set_clips function allocates new ClipList instances but does not pass those pointers back to the caller. The caller is probably attempting to use a garbage pointer as an initialise instance and that is why you are getting a segfault.
You need to pass the created objects back. You should use something like std::shared_ptr<> to do that instead of bare pointers.
Update on how to do this without using std::shared_ptr<>:
You need to keep track of ownership and deal with exceptions. In terms of the actual passing, the rule I use (originally from Lakos in "Large Scale C++ Software Design") is that parameters that are return values (as you are attempting to use them) are pointers, and read-only parameters are by value or const-reference. Return values come first.
So, your set_clips function should look like this:
void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips)
When you call set_clips you pass a pointer to each pointer that will receive the allocated value, and pass a const-reference to the placlips object that is not modified by the function.
You would all it something like this:
ClipList* clips = 0;
ClipList* flip_clips = 0;
set_clips(&clips, &flip_flips, placlips);
// ... then do whatever comes next.
But combining those rules with std::shared_ptr<> or boost::shared_ptr<> is better and the "modern C++" style.

Static C++ variable, without default constructor, loses value

I have a class with a static variable. Since I need a constructor that isn't the default, I'm getting a little confused, but I hope I did it well
Class
class Object3D{
public:
static Object3D ObjControl;
Object3D(); //this is here just for the initialization of the static variable
Object3D(Triangle *mesh);
Triangle *mesh;
};
At this point I need to create an Object3D and I do as below
bool Engine::OnInit() {
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
return false;
}
if((Surf_Display = SDL_SetVideoMode(WIDTH, HEIGTH, BBP, FLAGS)) == NULL) {
return false;
}
arma::colvec::fixed<3> upDirection;
upDirection << 0 << 1 << 0;
Camera cam(0.0, 0.0, 10.0, 10.0, 200.0, 90.0, upDirection);
Camera::CameraControl = cam;
arma::colvec::fixed<3> vertexA;
vertexA << -1 << 1 << 0;
arma::colvec::fixed<3> vertexB;
vertexB << 1 << 1 << 0;
arma::colvec::fixed<3> vertexC;
vertexC << 0 << -1 << 0;
Triangle tri(vertexA, vertexB, vertexC);
Triangle mesh[1];
mesh[0] = tri;
Object3D obj(mesh);
Object3D::ObjControl = obj; // PROBLEM! -> when the function extis from the OnInit ObjControl doesn't have anything inside.. it is like cleaned at the exit
return true;
}
The problem is the one that is inserted in the comment before the return.
Then when I need to pass that object to the rendering function, as below; the application closes because I'm trying to access to a location of memory not initialized
void Engine::OnRender(){
Rendering.WfRender(Object3D::ObjControl, Surf_Display, 1);
}
I think I'm doing something wrong with the static variable, but I did the same with a static variable for a Camera class, as you can see in the Engine::OnInit, and there everything works well. So I have no clue what's going on.
The main issue in your program is that you make a Triangle instance (mesh) in your function and that you pass a pointer to your static member variable ObjControl. When you leave the function, mesh is no longer available, so ObjControl points to an invalid instance. This could be solved by storing an actual Triangle instead of a pointer to a Triangle in Object3D or a container of Triangles if more are needed.
Does your Object3D class only hold onto the pointer to the mesh or take a copy of it?
Does it implement a deep-copy copy constructor?
I ask because your mesh is going out of scope after being assigned to obj, and obj is going out of scope after being assigned to the static variable. You need to either assign the mesh on the heap and hand that pointer to the static variable, or ensure the actual data is copied by correctly implementing the right constructors.
EDIT: Or, as this looks like games development, get it done quick and nasty! ;-)
Object3D::ObjControl.mesh = new Triangle(vertexA, vertexB, vertexC);
...and lose the local variables tri, mesh, and obj.

Class 2D array turns to arr [] when called by function C++

I have a university assignment and I am completely confused on how to pass the array correctly to prevent the array from being passed as a single array and not a 2D array.
We are to create a random maze generator that will allow us to play that maze too. We are using a specialized windows code to display the maze, but that's not were the problem is so Ill leave that out
My lecturer gave us the skeleton code to work from. What must I change to get it to work?
We have not learnt dynamic memory location or vectors. We have to use an array. Please Help!!?
Here is his code:
I have used the same and just added all the function parameters. I have not changed anything with 'maze' though
class MazeSquare
{
public:
bool leftWall, rightWall, bottomWall, topWall;
bool visited;
int steps;
MazeSquare() // constructor
{
Initialise();
}
void Initialise(void) // reinitialise a square for a new maze
{
leftWall = true; // create the maze square with all the walls
rightWall = true;
bottomWall = true;
topWall = true;
visited = false; // the robot has not visited the square yet
steps = 256; // greater than maximum possible number of steps
}
};
// constants
const int MAZE_SIZE = 16;
// function prototypes
void CreateMaze(MazeSquare maze[MAZE_SIZE][MAZE_SIZE]);
void SolveMaze(MazeSquare maze[MAZE_SIZE][MAZE_SIZE]);
void RestartMaze(MazeSquare maze[MAZE_SIZE][MAZE_SIZE]);
void MoveRobot(MazeSquare maze[MAZE_SIZE][MAZE_SIZE], int &x, int &y, Point click);
void DrawWindow(MazeSquare maze[MAZE_SIZE][MAZE_SIZE], int x, int y);
int ccc_win_main() // main function for a graphics program
{
MazeSquare maze[MAZE_SIZE][MAZE_SIZE]; // maze design
int x = 0, y = 0; // robot position
bool exit = false; // flag to control end of program
// initialise the random number generator
srand((unsigned int)(time(NULL)));
/* initialise the window coordinates here */
CreateMaze(maze); // create a new maze
DrawWindow(maze); // draw the image in the GUI window
do
{
// get a mouse click
Point click = cwin.get_mouse("Click a button or move the robot");
// handle the different types of mouse clicks
if (/* new button is clicked */)
{
CreateMaze(maze);
x = 0;
y = 0;
}
if (/* solve button is clicked */)
{
SolveMaze(maze);
}
if (/* restart button is clicked */)
{
RestartMaze(maze);
x = 0;
y = 0;
}
if (/* exit button is clicked */)
{
exit = true;
}
// handle robot moves
if (/* maze is clicked */)
{
MoveRobot(maze, x, y);
}
DrawWindow(maze);
} while (!exit);
return 0;
}
Confusion number one - You cannot pass arrays to functions in C++.
Confusion number two - You cannot declare arrays as function parameters in C++
Confusion number three - 2D arrays are single arrays, a 2D array is an arrays of arrays, therefore it's a 'single array` also. I guess I'm saying the term single array doesn't have much meaning.
Arrays are a confusing topic in C++. You cannot do everything you might expect to be able to do with them. Instead everything is done with pointers. The relationship beween arrays and pointers in C++ is another confusing topic. You really need to read a book. Any specific questions, ask again.
But on the bright side I don't see anything particularly wrong with your code. You're certainly are not passing single arrays to your functions, as you are worried about.
EDIT:
Perhaps I should make this a little clearer. On point two, this code
void CreateMaze(MazeSquare maze[MAZE_SIZE][MAZE_SIZE]);
certainly looks like you are declaring a function with an array parameter. But it doesn't. Instead the compiler takes the code and converts it into the equivalent code that uses pointers.
On point one, this code
CreateMaze(maze); // create a new maze
certainly looks like you are passing an array to a function, but again you are not. Given that code the compiler passes a pointer to the first element of your maze array, it doesn't pass the array itself.