This is the header:
class Board {
public:
friend class Game;
Board() = default;
Board(int n) : N(n) { }
Board& SetType(int, int, char);
void GetType(int, int);
Board& CreateEmptyBoard();
void BoardDisplay();
private:
int N = 0;// dimension
char Maze[15][15];
const static int MaxSize = 15;
};
class Game {
public:
Game() = default;
Game(int x, int y) : PosX(x), PosY(y) { }
void BuildGame();
void GameDisplay();
void MoveUp();
void MoveDown();
void MoveLeft();
void MoveRight();
private:
int PosX = 0;
int PosY = 0;
};
void Game::BuildGame() {
srand(time(NULL));
for (int i = 0; i < Board::N; i++) {
for (int j = 0; j < Board::N; j++) {
if (i == rand() % (Board::N) && j == rand() % (Board::N))
Board::Board& SetType(i, j, 'W');
}
}
}
In class Game's member function void BuildGame,I want to call member functionBoard& SetType(int,int,char) in class Board.I define this function in a header file and not show here. Then I build the project, I got invalid use of non-static data member 'Board::N' and 'SetType' was not declared in this scope. Like this
Where I wrong? I can't find it.
The compiler is letting you know that you are using an instance variable as a static. A static variable is associated with an entire class and not a single object, so it is called through the class name and not an object of the class. but it would need to be marked as static like so
class Board
{
public:
static Board& setType(int, int, char);
...
private:
static int N;
...
}
my instinct however tells me that you want to use it at an instance level, so you would write your void Game::buildGame() method using a Board that it creates (possibly making it an attribute of the Game class:
void Game::BuildGame() {
//make your board here. alternatively make an instance of the game
Board myBoard();
srand(time(NULL));
//in the following, use myBoard as the instance of a board.
for (int i = 0; i < myBoard.N; i++) {
for (int j = 0; j < myBoard.N; j++) {
if (i == rand() % (myBoard.N) && j == rand() % (Board::N))
myBoard.setType(i, j, 'W');
}
}
}
And a Board class that looks something like this. You will probably want your setType method to modify the instance and return void instead of returning another board reference.
class Board
{
public:
//this one will change this particular Board instance.
void setType(int, int, char);
//this one may make sense to be static if it is a factory method
//but why not use a constructor instead?
static Board& createEmptyBoard();
//maybe you meant something to reset the board to empty state.
void resetBoardToEmpty();
...
private:
int N;
...
}
while you're at it you might make it a struct (which has members public by default) as it seems to be a "hidden" holder class for the game, and this would alleviate the need to use a friend class (these are to be used judiciously as they can get messy really fast). using a struct would also allow you to make a ChessGame class that reuses the Board struct.
N isn't a static member of class Board, hence you'll need an instance of board to access it.
Your Game class actually needs to have a Board member variable to achieve that above mentioned instance.
Related
I have a class Game which contains an other object GameGrid:
Game.h
class Game
{
public:
Game(uint32_t GridSize);
private:
GameGrid _CurrentGrid;
}
Game.cpp
Game::Game(uint32_t GridSize) : _CurrentGrid(GridSize)
{
}
GameGrid.h
class GameGrid
{
public:
GameGrid(uint32_t GridSize);
void setGrid(const Grid& Grid);
const GameGrid::Grid getGrid(void) const;
private:
Grid _Grid;
}
GameGrid.cpp
GameGrid::GameGrid(uint32_t GridSize)
{
uint32_t i = 0;
uint32_t j = 0;
_Grid.assign(GridSize, std::vector<unsigned int>(GridSize));
for (i = 0; i < GridSize; i++)
{
for (j = 0; j < GridSize; j++)
{
_Grid.at(i).at(j) = 0;
}
}
}
void GameGrid::setGrid(const GameGrid::Grid& Grid)
{
_Grid = Grid;
}
const GameGrid::Grid GameGrid::getGrid(void) const
{
return _Grid;
}
Now I have my application, which uses the game class
Game* MyGame = new Game(4);
How can I create a copy function for this pointer to the Game-Object, so that I can clone the object.
I´ve tried it with the assignment operator
Game& operator=(Game const& Ref);
Game& Game::operator=(Game const& Ref)
{
if (&Ref != this)
{
this->~Game2048();
new (this) Game2048(Ref);
}
return *this;
}
But this solution doesn´t work and my original object got changed too, when I change the clone.
Does someone has a hint for me?
Thank you!
Don't create the copy constructor yourself and let the compiler do it for you, then just use objects:
Game MyGame{4};
Game gameClone = MyGame;
There's no reason to use a raw pointer here.
I agree to what #SombreroChicken hast said.
I just want to point out the difference between a deep copy and shallow copy.
If your class Contains some pointer as private member data, you have to be aware, that only the pointer is copied and not the data to which is being pointed. Here is a nice in depth explanation of what I said.
I am trying to write a simple game in C++ and currently have my Game_Window class holding an array of pointers to game objects as follows:
class Game_Window {
private:
int width;
int height;
int num_objects;
public:
char** objects;
/* The rest of the class goes here */
}
Inside my Game_Window class I want to define a function that calls the "print()" function on all objects held in the game window "objects" array as follows.
void Game_Window::print_objects() {
for (int i = 0; i < num_objects; i++) {
(objects[i])->print(); /* THE PROBLEM IS HERE */
}
}
When I compile I get the following error:
game_window.cpp:29:15: error: member reference base type 'char' is not a structure or union
(objects[i])->print();
~~~~~~~~~~~~^ ~~~~~
1 error generated.
All objects in my game have a "print()" function so I know that's not the issue. Any help would be much appreciated.
I think I figured it out. I created a class called Game_Object that all my game objects will inherit, and gave it a print() method.
class Game_Object {
private:
Location location;
public:
Game_Object();
Location *get_location() { return &location; }
void print();
};
class Diver : public Game_Object {
public:
explicit Diver(int x, int y);
};
class Game_Window {
private:
int width;
int height;
int num_objects;
public:
Game_Object** objects;
explicit Game_Window(int width, int height);
~Game_Window();
int get_width() { return width; }
int get_height() { return height; }
int get_object_count() { return num_objects; }
bool add_object(Game_Object object);
void print_objects();
};
The invocation of print() is now:
void Game_Window::print_objects() {
for (int i = 0; i < num_objects; i++) {
objects[i]->print();
}
}
I ran it and it game me no errors.
The type of Game_Window::objects is char** (pointer to pointer to char). Hence objects[i] is the ith pointer, and pointers don't have print() methods, which is why (objects[i])->print(); fails with the described error.
Perhaps you meant to use print(objects[i]); instead?
I defined a class in the header file like this:
class myClass
{
public:
void test();
void train();
private:
bool check;
}
Then in the cpp file, I did this:
void myClass::test()
{
int count = 9;
//some other work
}
void myClass::train()
{
int newValue = count;
....
}
Then without surprise, I got an error saying count is not defined. So what I want to do is in my train function use the count value that is defined in the test. Is there any good way to do this without using any additional dependencies? Thank you.
Well yes. That's called a member variable. Exactly like your bool check;.
Do
private:
bool check;
int count;
and then use it directly in your functions.
void myClass::test()
{
count = 9;
//Same as this->count = 9;
}
void myClass::train()
{
int newValue = count;
//Same as int newValue = this->count;
}
In your example, when method test finishes its work, count variable does not exist anymore, so there's no way of accessing it. You have to ensure, that its lifetime will be long enough to be accessed from another place. Making it a class field solves the problem (this is what class fields are for :)).
Do it this way:
class myClass
{
public:
void test();
void train();
private:
bool check;
int count; // <- here
}
and then
void myClass::test()
{
count = 9;
//some other work
}
But that's not the only solution. You can do it in another way, say:
class myClass
{
public:
int test()
{
// do some work
return 9;
}
void train(int count)
{
int newValue = count;
}
}
// (somewhere)
myClass c;
int count = c.test();
c.train(count);
That all depends on what test, train and count are for...
I'm making a card game and I have a few classes.
I have a Hand class, a Player Class, a "Column" class (where the cards are placed on the screen after the hand) and I need each class to have access to the other classes' variables.
class Hand
{
private:
int **Hx,Hy;** //Hand X, Hand Y
int HAmount;//Amount of cards in Hand
int HOwner; //Player 1/2
int Limit; //Limit of cards in Hand
int HContents[8]; //Card Position in 54 card deck NOT card value.
bool Removed;
public:
Hand();
void Lim();
void Get_Card();
void Show();
void Set_Values(int y, int Own);
};
Then in another class I need to have access to some of the variables above.
void Card::show()
{
if((apply == true)
{
if((Track == true)&&(SelNum == TNum)&&(TOwner == COwner))
{
ScnPos = TAmount;
x = Tx;
y = Ty + ScnPos*10;
}
if((Hand == true)&&(**HOwner** == COwner))
{
x = **Hx** + ScnPos*45;
y = **Hy;**
}
apply_surface(x,y,Cards,Screen,&Clip[Pos]);
}
}
I've tried using class friendship and other methods but I can't make it work.
(obviously I have more variables which need this same treatment)
(ignore any errors in my code)
The errors in your code are the real problem here. there is no reason that a Card will access a Hand's private member. this is design error, and your other problems are just trying to tell you that.
Well, you should make getters and setters for your variables. E.g.:
class Test {
private: int a;
public: int GetA() {
return this->a;
}
void SetA(int a) {
this->a = a;
}
}
I'm programming a chessboard, and I've a base class chesspiece (schaakstuk in my language) and all the pieces like king, queen, are derived from that base class.
Now I wanted to create an object and fill a array with objects to start the game. Visual studio is giving me some errors on this line:
bord[1][kolom] = new Schaakstuk(Schaakstuk::WIT);
bord[6][kolom] = new Pion(Schaakstuk::ZWART);
that it is impossible to create from a abstract class. I don't see the error, first I thought it was that I was using a pure virutal function in my derived class but that isn't it, I'm only using a pure virtual function in my base class.
Constructor
for( int kolom = 0; kolom < SIZE; kolom++ )
{
bord[1][kolom] = new Pion(Schaakstuk::WIT);
bord[6][kolom] = new Pion(Schaakstuk::ZWART);
}
Pion.h
#include "Schaakstuk.h"
#include "Exceptions.h"
#ifndef PION
#define PION
class Pion: public Schaakstuk
{
public:
Pion(void);
~Pion(void);
bool ZetIsLegaal( int rij1, int kolom1, int rij2, int kolom2 ) const;
void PrintStuk( void ) const;
void GeefCor( int tabel [8][2], int rij, int kolom, int rij1, int kolom1) const;
bool IsPion( void ) const { return true; };
private:
bool ControleerZet( int rij1, int kolom1, int rij2, int kolom2 ) const;
};
#endif
Schaakstuk.h
#ifndef SCHAAKSTUK
#define SCHAAKSTUK
static const int SIZE1 = 8;
class Schaakstuk
{
public:
enum kleurType { WIT, ZWART };
Schaakstuk(kleurType kleur = WIT)
{
this->kleur = kleur;
};
virtual bool ZetIsLegaal( int rij1, int kolom1, int rij2, int kolom2 ) = 0;
virtual void PrintStuk( void ) = 0;
virtual void GeefCor( int tabel [8][2], int rij, int kolom, int rij1, int kolom1) = 0;
kleurType GeefKleur( void ) const { return kleur; };
virtual bool IsPion( void ) = 0;
protected:
bool static NietOutOfBounds( int rij, int kolom );
private:
kleurType kleur;
};
#endif
is my dropbox with the code files. Can someone help me?
this are the errors:
http://pastebin.com/82j08rry
and here is the full code
http://ideone.com/sWjxS
If the error is along the lines of "Can't instantiate abstract class" then the next line should tell you which method is abstract.
Most likely is you have declared a pure virtual in the base class but didn't override it (or override it properly; see below) in the derived class.
First check to make sure you have an override in Schaakstuk and Pion, and then check to make sure you haven't changed the signature at all. This could be a different const/volatile qualification, or different method parameters.
The word 'abstract' is the give away. You need to create from a concrete class - i.e. the compiler needs to know everything about the ins and outs of that object.