Getting Unresolved External error - c++

I have made a class and it compiles with no syntax errors, but I get 6 unresolved external symbols?
THE CLASS:
struct CELL {
private:
static bool haslife;
static int x;
static int y;
public:
static bool has_life()
{
return haslife;
}
static void set_coords(int xcoord, int ycoord)
{
x = xcoord;
y = ycoord;
}
static void get_coords(int &xcoord, int &ycoord)
{
xcoord = x;
ycoord = y;
}
};
class cell_grid {
private:
static int cell_size;
static int cell_count_x;
static int cell_count_y;
CELL **cell;
public:
cell_grid();
cell_grid(unsigned int width,unsigned int height, unsigned int cellsize)
{
//set size based on cellsize
this->cell_size = cellsize;
this->cell_count_x = floor((double)width / this->cell_size);
this->cell_count_y = floor((double)height / this->cell_size);
this->cell = new CELL*[this->cell_count_y];
for(int i = 0; i < this->cell_count_y; i++)
{
cell[i] = new CELL[this->cell_count_x];
}
for(int y = 0; y < this->cell_count_y; ++y)
{
for(int x = 0; x < this->cell_count_x; ++x)
{
int cur_x = x * this->cell_size;
int cur_y = y * this->cell_size;
this->cell[x][y].set_coords(cur_x,cur_y);
}
}
} //end of constructor
static int get_cell_size()
{
return cell_size;
}
static void render(BITMAP *buff)
{
circlefill(buff,70,70,60,makecol(27,37,0));
}
};
MAIN
int main()
{
start_allegro();
cell_grid *grid = new cell_grid(scr_w,scr_h,10);
grid->render(buffer);
//Main Loop
while (!done && !key[KEY_ESC]) //until 'X' pressed or ESC
{
//***** Start Main Code Here *****
while (speed_counter > 0)
{
//render the buffer to the screen
blit(
buffer,
screen,
0,0,0,0,
scr_w,
scr_h);
clear_bitmap(buffer);
speed_counter --;
}
//***** End Main Code Here *****
rest(1); //Normalize cpu usage
}
return 0;
}
END_OF_MAIN()
Thanks

Don't define all of the class variables as static.
When you define a data member as static it means there is only one single instance of it. This doesn't seem to be what you want to do here.
Instead of
private:
static bool haslife;
static int x;
static int y;
write:
private:
bool haslife;
int x;
int y;
Further more, when you define a static member, you need to define it again in the CPP file and initialize it with a value. It doesn't look like you're doing that and that's why you're getting the linker errors.
Also, next time you post something, make sure you actually ask a question rather than just simply stating facts.

Related

Making a local struct instance accessible to another function (C++)

So I have a struct which holds variables for entities within a game (hit points, x and y coordinates, etc) and I have the struct declared globally. However, I have the instances created in a "setup" function and want their variables to be modified in a separate "logic" function. But obviously, since the instances are local to the "setup" function, the "logic" function can't modify their variables.
This is a simplification of my current code.
// Global space
struct entity {
int hp, atk, x, y;
};
void Setup()
{
entity dummy;
dummy.hp = 10;
dummy.atk = 2;
dummy.x = 5;
dummy.y = 5;
}
void Logic()
{
// if(dummy is attacked)
dummy.hp -= 4;
}
int main()
{
Setup();
while(game is not over)
Logic();
}
There are a few different ways you can solve this:
move dummy into global scope:
struct entity {
int hp, atk, x, y;
};
entity dummy;
void Setup()
{
dummy.hp = 10;
dummy.atk = 2;
dummy.x = 5;
dummy.y = 5;
}
void Logic()
{
if (dummy is attacked)
dummy.hp -= 4;
}
int main()
{
Setup();
while (game is not over)
Logic();
}
Move dummy into main(), and then pass it by reference (or pointer) to Setup() and Logic():
struct entity {
int hp, atk, x, y;
};
void Setup(entity &e)
{
e.hp = 10;
e.atk = 2;
e.x = 5;
e.y = 5;
}
void Logic(entity &e)
{
if (e is attacked)
e.hp -= 4;
}
int main()
{
entity dummy;
Setup(dummy);
while (game is not over)
Logic(dummy);
}
an extension of #2 above, you could then move Setup() and Logic() into the struct itself:
struct entity {
int hp, atk, x, y;
void Setup();
void Logic();
};
void entity::Setup()
{
hp = 10;
atk = 2;
x = 5;
y = 5;
}
void entity::Logic()
{
if (is attacked)
hp -= 4;
}
int main()
{
entity dummy;
dummy.Setup();
while (game is not over)
dummy.Logic();
}

C++ Private Memeber Variable Inaccessible to Memeber Function

I am working on recreating pong, and while moving drawPaddle function from the main Game class to the Paddle class I ran into an issue where the function cannot read the member variables (even though they are in the same class). The class is in a header file and the function definitions are in a cpp file. The variables in question are height, width, xPos, and yPos.
Paddle class
#include "Graphics.h"
class Paddle
{
public:
void setX(int z)
{
xPos = z;
}
int getX()
{
return xPos;
}
void setY(int z)
{
yPos = z;
}
int getY()
{
return yPos;
}
int getWidth() {
return width;
}
void setHeight(int z)
{
height = z;
}
int getHeight()
{
return height;
}
void setPlayer(bool z)
{
player = z;
}
bool getPlayer()
{
return player;
}
private:
//functions
void drawPaddle(Graphics& gfx);
void updatePaddle(Graphics& gfx);
//variables
int xPos;
int yPos = Graphics::ScreenHeight / 2 - Paddle::height / 2;
bool player;
static constexpr int width = 20;
int height = 100;
};
drawPaddle function
#include "Paddle.h"
#include "Graphics.h"
void drawPaddle(Graphics gfx)
{
for (int i = 0; i < width; i++)
{
for (int j = 0; j < Paddle::height; j++)
{
gfx.PutPixel(p.getX() + i, p.getY() + j, Colors::White);
}
}
}
As you can see I've tried accessing it with the raw variable (tells me the variable is undefined), through the class (tells me the variable is inaccessible), and using the getter for it (failed because it must be in reference to a specific instance). Anyone have any idea what I am doing wrong? Thanks.
In the definition, you didn't indicate that drawPaddle was a member of Paddle, so it was treating that definition as a definition of a free function, not a member function. Free functions wouldn't have access to the private members.
It should start with
void Paddle::drawPaddle(Graphics gfx)

Accessing double pointer from another class

I'd like to access to a double pointer which is located in another class "Board".
class Board
{
public:
Board(void);
Board(unsigned int xSize, unsigned int ySize);
~Board(void);
void SetObjectManager(ObjectManager* pObm);
void SetBlock(Block* block);
void LoadBoard(void);
void InitBoard(void);
//Other Functions...
private:
ObjectManager* m_obm;
Block* m_block;
//pointer to pointer to a int. (for 2 dimensional-array)
int **m_board;
};
First, the Board class. at the last line of class, you can see m_board.
I want to change this value in outside of this class.
Like this,
void Block::InitBlock(void)
{
int randPiece = Random::GIRand().RandInt(0, 1);
int randPos = Random::GIRand().RandInt(0, 10);
switch (randPiece)
{
case 0:
m_piece[2][1] = 1;
m_piece[2][2] = 1;
m_piece[2][3] = 1;
m_piece[3][3] = 1;
break;
//Other cases are here...
}
std::cout << "RandPos : " << randPos << std::endl;
std::cout << "RandPiece : " << randPiece << std::endl;
for (int y = 0; y < m_ySize; ++y)
{
for (int x = 0, pX = randPos; x < m_xSize; ++x, ++randPos)
{
if (m_piece[x][y] != 0)
m_board->SetBoardStatus(randPos, y, 1);
}
}
}
But, When I run this program, It blows up at SetBoardStatus(int, int, int)
SetBoardStatus looks like this,
void Board::SetBoardStatus(int x, int y, int value)
{
m_board[x][y] = value; //Visual Studio breaks the program here.
}
I allocate the double pointer properly.
And I set the board at the outside of this classes.
void Block::SetBoard(Board* board)
{
m_board = board;
}
And this is my block class.
class Block
{
public:
Block(void);
~Block(void);
void SetObjectManager(ObjectManager* pObm);
void LoadBlock (void);
void InitBlock (void);
void UpdateBlock (void);
void ReleaseBlock (void);
void SetBoard(Board* board);
private:
ObjectManager* m_obm;
Board* m_board;
int **m_piece;
int m_xSize;
int m_ySize;
};
Consider inheriting Block in Board; This will eliminate any possible de-referencing errors or bugs, as you can access the pointer right away.

My object is being destructed right after being constructed

I'm trying to construct a two-dimensional boolean array with a class I've created called Grid. The Grid object is a private member class of another class called GameOfLife. Whenever I create a GameOfLife object with the parameters belove, the Grid object first gets created with the default constructor, then it gets created again with the constructor with parameters, and then for some reason Grid's deconstructor runs and deletes everything ? I'm really out of ideas :p I'm running MinGW GCC on Eclipse Luna.
Main.cpp
const int HEIGHT = 25;
const int WIDTH = 25;
#include <iostream>
#include "GameOfLife.h"
int main(int argc, const char * argv[]) {
GameOfLife game = GameOfLife(HEIGHT, WIDTH, false);
game.play();
return 0;
}
Grid.h
#ifndef __Game_Of_Life__Grid__
#define __Game_Of_Life__Grid__
#include <stdio.h>
class Grid {
public:
Grid(int y, int x, bool state);
Grid();
void allocate(int x, int y, bool state);
void deallocate();
void set(int x, int y, bool state);
bool get(int x, int y);
void setAll(bool state);
void switchBoards();
~Grid();
private:
bool ** oldGeneration;
bool ** newGeneration;
int height;
int width;
};
#endif /* defined(__Game_Of_Life__Grid__) */
Grid.cpp
#include "Grid.h"
Grid::Grid(int y, int x, bool state) {
allocate(x, y, state);
}
void Grid::allocate(int x, int y, bool state) {
height = y;
width = x;
oldGeneration = new bool*[height];
newGeneration = new bool*[height];
for (int i = 0; i < height; i++) {
oldGeneration[i] = new bool[width];
newGeneration[i] = new bool[width];
}
}
Grid::~Grid() {
deallocate();
}
void Grid::switchBoards() {
bool ** temp = oldGeneration;
oldGeneration = newGeneration;
newGeneration = temp;
delete temp;
}
bool Grid::get(int x, int y) {
return oldGeneration[y][x];
}
void Grid::set(int x, int y, bool state) {
newGeneration[y][x] = state;
}
void Grid::deallocate() {
if (oldGeneration != NULL || newGeneration != NULL) {
for (int i = 0; i < height; i++) {
delete [] oldGeneration[i];
delete [] newGeneration[i];
}
delete [] oldGeneration;
delete [] newGeneration;
}
return;
}
Grid::Grid() {
oldGeneration = NULL;
newGeneration = NULL;
width = 0;
height = 0;
}
void Grid::setAll(bool state) {
for (int i = 0; i < height; i++) {
for (int n = 0; n < width; n++) {
newGeneration[i][n] = state;
}
}
}
GameOfLife.h
#ifndef __Game_Of_Life__GameOfLife__
#define __Game_Of_Life__GameOfLife__
#include <stdio.h>
#include "Grid.h"
#include <iostream>
class GameOfLife {
private:
Grid board;
public:
GameOfLife(int y, int x, bool state);
GameOfLife();
~GameOfLife();
void play();
void welcome();
void makeBoard();
void updateBoard();
int findAliveNeighbours(int x, int y);
};
#endif /* defined(__Conway__GameOfLife__) */
GameOfLife.cpp
#include "GameOfLife.h"
const int WIDTH = 100;
const int HEIGHT= 75;
GameOfLife::GameOfLife(int y, int x, bool state) {
board = Grid(y, x, state);
}
GameOfLife::GameOfLife() {
board = Grid();
}
GameOfLife::~GameOfLife() {
board.deallocate();
}
void GameOfLife::play() {
welcome();
makeBoard();
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
updateBoard();
std::cout << std::endl;
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
}
void GameOfLife::makeBoard() {
int x1,x2,x3,x4, y1,y2,y3,y4;
x1 = 10; y1 = 10;
x2 = 10; y2 = 11;
x3 = 10; y3 = 12;
x4 = 11; y4 = 13;
int x5 = 0; int y5 = 0;
board.set(x1, y1, true);
board.set(x2, y2, true);
board.set(x3, y3, true);
board.set(x4, y4, true);
board.set(x5, y5, true);
}
void GameOfLife::welcome() {
std::cout << "Welcome to Conway's Game Of Life"
<< std::endl;
}
GameOfLife::GameOfLife(int y, int x, bool state) {
// board is a member variable that gets initialized
// with the default constructor.
// Then it gets replaced by assignment with a different
// Grid object. The temporary object gets deleted at
// the end of the line.
board = Grid(y, x, state);
}
Change the implementation to:
GameOfLife::GameOfLife(int y, int x, bool state) : board(y, x, state) {}
Similarly, change the default constructor to:
GameOfLife::GameOfLife() {}
The more important problem that needs to be fixed is that you are breaking The Rule of Three.
You need to add proper implementations of the copy constructor and the copy assignment opertor in Grid.
The other, and better, option is to change the internal data of Grid to
std::vector<std::vector<bool>> oldGeneration;
std::vector<std::vector<bool>> newGeneration;
Then, the compiler generated copy constructor and copy assignment operator will be good enough.

Loop through an array

I would like to know, how to loop through a array of int to get its value and set its value. I know how to use the for loop to to get instantly, but I am not sure how it works, when I am using in user created objects and esp using the get set method.
I am totally new to this and have very little guidance from my lectures. I hope you guys can assist to help me. This up to where I have done.
//point.h
class point {
private:
int x[4];
public:
int getx();
void setx();
};
//point.cpp
class point {
point::getx(){
// ??????
}
point::setx(){
// ???????
}
//main.cpp
int main(){
point objPoint;
objPoint.setx(/* ???? */);
???? = objPoint.getx();
}
First of all, your getx method should return int*, not just int, and your setx should receive const int* as parameter. Second, in your point.cpp file you shouldn't redeclare class point.
int* point::getx() { //version with copying
int* ans = new int[4];
for (int i = 0; i < 4; i++) {
ans[i] = x[i];
}
return ans;
}
void point::setx(const int* y) {
for (int i = 0; i < 4; i++) {
x[i] = y[i];
}
}
Then you can use them like this
int y[4] = {1, 2, 3, 4};
int* z;
objPoint.setx(y);
z = objPoint.getx();
Just don't forget to delete[] z when you're done.
If I'm understanding you correctly, you probably want something like more this:
point.h:
class Point{
private:
int x, y;
public:
int getx();
int gety();
void setx(int value);
void sety(int value);
};
point.cpp
int Point::getx() { return x; }
int Point::gety() { return y; }
void Point::setx(int value) { x = value; }
void Point::sety(int value) { x = value; }
main.cpp
int main(int argc, char *argv[])
{
Point objPoint;
objPoint.setx(1);
int x = objPoint.getx();
cout << "x=" << x << endl;
return 0
}
Even better, you might wish to define a constructor like Point (int xvalue, int yvalue).
IMHO ...