I have code like this(all made for a minimal, reproducible example):
enum class gameState{
Normal,
Special};
class Piece{
public: Vector2i position;
int shape;};
class Board{
public: int array[8][8];
std::vector<Piece> f;
Board() : f(std::vector<Piece>(32)) {}; };
void promotion(int shape, gameState &state, Board &b){
state = gameState::Special;
b.array[b.f[0].position.x][b.f[0].position.y] = shape;
b.f[0].shape = shape;};
And then I try to call them in main:
int main(){
gameState state = gameState::Normal;
Board b;
promotion(1, state, b);
return 0;};
The problem is that it seems to correctly pass by reference for gameState state object, it doesn't modify Board b object, which isn't supposed to happen. How can I correctly pass Board b by reference (or a pointer)?
P.S.: Vector2f is simply a 2D vector the SFML library uses.
Actually, Board in your code is being (CORRECTLY) passed by reference to promotion function.
Are you sure it is not changed after function call?
What it prints if you do:
int main(){
gameState state = gameState::Normal;
Board b;
std::cout << b.array[b.f[0].position.x][b.f[0].position.y] <<std::endl;
promotion(1, state, b);
std::cout << b.array[b.f[0].position.x][b.f[0].position.y] <<std::endl;;
return 0;
};
Related
I'm trying to save an Object in an 2D Vector. The vector needs to be sized at runtime. Therefore i use the resize function as mentioned in many other issues.
Her an broke down code example of my problem. So the code might not make sense but I get the same error.
Animation.h
class myPoint{
public:
int x, y;
myPoint(){}
myPoint(int x, int y) : x(x), y(y) {}
};
class AnimationFrame {
private:
std::vector<std::vector<myPoint>> sprites; //the important part
public:
void addSpritePoint(myPoint gridPos, myPoint tilePos);
...
};
class Animation {
private:
std::vector<AnimationFrame*> animationFrames;
public:
...
};
Animation.cpp
Animation::Animation() {}
int Animation::addAnimationFrame() {
AnimationFrame *newAnimationFrame = new AnimationFrame();
this->animationFrames.emplace_back(newAnimationFrame);
}
//AnimationFrame class
AnimationFrame::AnimationFrame(){
int w = 3; //just for the test
int h = 3;
this->sprites.resize(w, std::vector<myPoint>(h, myPoint(0,0)));
}
void AnimationFrame::addSpritePoint(myPoint gridPos, myPoint tilePos) {
this->sprites[gridPos.x][gridPos.y] = tilePos;
//printf(""); //breakpoint here
}
main.cpp
int main() {
Animation *a = new Animation();
a->addAnimationFrame();
a->getAnimationFrame(0).addSpritePoint(myPoint(0,0), myPoint(1,1));
a->getAnimationFrame(0).addSpritePoint(myPoint(0,1), myPoint(2,2));
a->getAnimationFrame(0).addSpritePoint(myPoint(0,2), myPoint(3,3));
}
I expect that the sprites 2D vector from my AnimationFrame class holds the values. When the first breakpoint kicks in the the Point(1,1) is in sprites(0,0) but when i now skip to the next breakpoint the values in sprites(0,0) is (0,0) again. So it resets the value. And i have no clue why.
The problem comes from the fact that Animation::getAnimationFrame() returns a copy of its internal data:
AnimationFrame Animation::getAnimationFrame(int frame) const;
So this modifies a temporary object and has no effect once the full expression has been evaluated:
a->getAnimationFrame(0).addSpritePoint(myPoint(0,0), myPoint(1,1));
The fix is simple: return by reference:
const AnimationFrame& Animation::getAnimationFrame(int frame) const
{
return *animationFrames[frame];
}
AnimationFrame& Animation::getAnimationFrame(int frame)
{
return *animationFrames[frame];
}
(yes, you need a const and a non-const version)
Greetings C++ community !
I am new to C++ i have this code example :
class Player
{
public:
int pdamage;
int phealth;
/* ... other data members and some void member functions (getName etc.) */
};
class Ennemy
{
public:
int edamage;
int ehealth;
};
**/*here i would like to use current objects parameters for calculation and return to current player instance(current player object) the health value.*/**
int playerHit(this.Player.damage,this.Enemy.ehealth)
{
ehealth = this.Ennemy.ehealth - this.Player.damage;
return ehealth;
};
int ennemyHit(this.Player.phealth,this.Enemy.edamage)
{
phealth = this.Player.phealth - this.Ennemy.edamage ;
return ehealth;
};
int main()
{
/*....*/
return 0;
}
Returning to the post question:
How i use current object parameters in a function for calculations?
/*Since i am new to stackoverflow and C++ Thanks for all advises and suggestions and critics ! */
In C++ you would pass the calles either as pointer or reference
int playerHit(const Player& player, const Ennemy& ennemy)
{
return ennemy.ehealth - player.pdamage;
};
I'll start out with some context.
Making a simple game.
I have two classes, one called BouncingBall, and the other called ASCIIRenderer.
I have a list of instructions to follow, but some of the instructions aren't entirely clear.
First instruction was to create a pointer in BouncingBall called m_pRenderer, and have it point to a member variable in ASCIIRenderer. It wasn't specified which member variable I had to point to, and both existing member variables in there were private, so I made my own and called it Renderer.
Second instruction (the one I need help with) is when I'm writing a function for the BouncingBall class to call SetPixel using the m_pRenderer, and with three variables as parameters.
SetPixel is the name of a public function in the ASCIIRenderer class, and the instruction states I have to call it by using the pointer somehow.
Summary: I need to call a class' function from within the function of a separate class using a pointer.
Could someone explain to me what syntax I would use to accomplish this?
Based on the details you provided this is what I gathered. Assuming the BouncingBall class would get the X and Y pos and call the function foo with
the X and Y values to have the Renderer set. Also, I don't know how you will
initialize the pointer as it's not detailed above. Hope this helps.
class BouncingBall
{
public:
void foo( int posX, int posY)
{
m_pRenderer->setPixel( posX, posY);
}
private:
ASCIIRenderer* m_pRenderer;
};
The code I have included below shows an example of a class, in this case Ball, having a pointer to another class, in this case Renderer, injected and stored for later use.
The Ball class can then call public functions on the Renderer class using the 'arrow' syntax pointer->MemberFunction(arg1, arg2);
#include <iostream>
class Renderer
{
public:
/* Constructor and other functions omitted */
void SetPixel(const int x, const int y) const;
};
void Renderer::SetPixel(const int x, const int y) const
{
std::cout << "Set pixel: (" << x << ", " << y << ")" << std::endl;
}
class Ball
{
public:
Ball(const Renderer *const renderer, const int posX, const int posY);
void Render() const;
private:
const Renderer* _renderer;
int _posX;
int _posY;
};
Ball::Ball(const Renderer *const renderer, const int posX, const int posY)
: _renderer(renderer), _posX(posX), _posY(posY)
{}
void Ball::Render() const
{
_renderer->SetPixel(_posX, _posY);
}
int main()
{
const Renderer renderer;
const Ball ball(&renderer, 10, 20);
ball.Render();
return 0;
}
The output of the program is: Set pixel: (10, 20)
I'm still confused with pointers, maybe you could enlighten me a bit.
I'm having some classes pointing to each other and don't get the way to access them in the right way.
#include <vector>
#include <iostream>
class Player;
class Trainer;
class Team {
Trainer* trainer_;
std::vector<Player*> player_;
public:
std::vector<Player*> player() { return player_; }
Trainer* trainer() { return trainer_; }
std::vector<Player*> get_playerlist(){
return player_;
};
};
class Player {
public:
void setteam_(Team* x){
team_ = x;
}
private:
Team* team_;
};
class Trainer {
Team* Team_;
};
int main()
{
Player player1;
Team team1;
std::vector<Player*> playerlist;
player1.setteam_(&team1);
playerlist = team1.get_playerlist();
std::cout << playerlist.size();
std::cin.get();
return 0;
}
In the main there is player1 created and assigned to the playerlist of team1, now he should somehow appear there when i get the playerlist. But the output of this code is that the size of the playerlist of team 1 is still 0. What did I do wrong ?
Your Team class has no method that actually adds players to the player_ vector. Setting the team_ pointer to the team1 instance is not sufficient.
player1.setteam_(&team1);
What happens next is:
void setteam_(Team* x){
team_ = x;
}
Here you are stating that this Player has pointer to Team set to the same address as x. But this doesn't mean that this Team object has pointer to player in std::vector. This doesn't happen automaticly, you need something like:
void setteam_(Team* x){
team_ = x;
x->addPlayer( this); // add to vector
}
This question already has answers here:
Why is virtual function not being called?
(6 answers)
Closed 9 years ago.
AoA,
I am making a console game of chess, But I am stuck at polymorphism, below is the classes and functions definitions
/* old Part
//Base Class
class Piece /*Parent class */
{
protected:
Position* pCoord;
std::string color;
char symbol;
public:
Piece(Position* Coord,std::string Color,char symbol);
Position GetCurrentPos();
std::string GetColor();
void SetColor(std::string color);
void Draw();
virtual bool SetPos(Position* newPos){MessageBox(NULL,L"Virtual Running",L"Error",MB_OK); return true;};
virtual ~Piece();
};
/* Inherited classes */
//Child classes
class Pawn: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Pawn(Position* Coord,std::string Color,char symbol);
~Pawn();
std::vector<Position>* GetThreatendFields();
bool isValidMove(Position* newPos);
bool SetPos(Position* newPos);
};
//Child classes
class Bishops: public Piece
{
private:
std::vector<Position>* allowPos;
public:
Bishops(Position* Coord,std::string Color,char symbol);
~Bishops();
std::vector<Position>* GetThreatendFields();
bool isValidMove(Position* newPos);
bool SetPos(Position* newPos);
};
//Here is the implementation of child class function SetPos
bool Pawn::SetPos(Position* newPos)
{
bool isSet = false;
this->pCoord = new Position();
this->pCoord = newPos;
isSet = true;
MessageBox(NULL,L"Child function running",L"Yuhuu!",MB_OK);
return isSet;
}
class ChessBoard
{
private:
Position ptr; //dummy
int SelectedPiece;
vector<Piece> pPieceSet;
bool isSelected;
public:
ChessBoard();
~ChessBoard();
void ShowPieces(Player *p1,Player *p2);
void Draw();
void MouseActivity();
void Place(Piece& p);
};
//it just shows the peices acquired from player objects..dummy vector pointer
void ChessBoard::ShowPieces(Player* p1,Player* p2)
{
std::vector<Piece>* vPiece = p1->GetPieces();
for( int i=0;i<vPiece->size();i++ )
{
Piece& piece = vPiece->at(i);
Place(piece);
piece.Draw();
}
vPiece = p2->GetPieces();
for( int i=0;i<vPiece->size();i++ )
{
Piece& piece = vPiece->at(i);
Place(piece);
piece.Draw();
}
}
*/
/*new part
I did what you say
Player::std::vector<Piece*> *vPieceSet;
Player::Player(int turn)
{
this->turn = turn%2;
this->vPieceSet = new std::vector<Piece*>;
}
void Player::Initialize() //Initial and final ranges for position
{
//Initialization of pieces to their respective position
Position pos;
Piece *pPiece;
if( this->turn == 0 )
{
this->SetName("Player 1");
for( int i=8;i<16;i++ )
{
pos.SetPosition(i);
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
this->vPieceSet->push_back(pPiece);
}
//other classes same as above
}
It runs fine at initialzation function(stores all classes fine) but when use function to get the vector object
std::vector<Piece*>* Player::GetPieces()
{
std::vector<Piece*>* tPieces = this->vPieceSet;
return tPieces;
}
//In main.cpp
it doesnot return the vector object
Player p1(0),p2(1);
p1.Initialize();
p2.Initialize(); //initialization done perfectly while debugging
vector<Piece*> *obj = p1.GetPieces(); //returns garbage
Piece* pObj = obj->at(0); //garbage
cout<<pObj->GetColor(); // garbage
*/new part
Sounds like I have another problem!
When you use polymorphism, what you are really trying to do is instantiate an object of derived type and call the methods on that object through a pointer or reference to the base object.
class Foo
{
public:
virtual void DoIt () { cout << "Foo"; }
};
class Bar
:
public Foo
{
public:
void DoIt () { cout << "Bar"; }
};
int main()
{
Foo* foo = new Bar;
foo->DoIt(); // OUTPUT = "Bar"
Foo& fooRef = *foo;
fooRef.DoIt(); // OUTPUT = "Bar"
}
In order for this to work, you need to use either a pointer or a reference to the object. You can't make a copy of the object using a the base class. If you make a copy, you will slice the object.
int main()
{
Foo* foo = new Bar;
foo->DoIt(); // OK, output = "Bar"
Foo fooCopy = *foo; // OOPS! sliced Bar
fooCopy.DoIt(); // WRONG -- output = "Foo"
}
In your code, the Piece class is intended to be polymorphic, and in your ChessBoard class you have a vector of this class:
class ChessBoard
{
private:
vector<Piece> pPieceSet;
};
Since this is a vector of the Piece object itself, and not a pointer-to-Piece, anything you put in here will be sliced. You need to change pPieceSet to be a vector of pointers-to-Piece:
vector <Piece*> pPieceSet;
You have further problems in Initialize, which need to be refactored anyway. For one thing, you have another vector of Piece objects, and there are two problems here. First, it needs to be a vector of pointers, and second, why do you need another vector at all when there is already one associated with the ChessBoard? I didn't thouroughly examine your code so maybe you do need it, but this seems like an error. There should probably just be one collection of pieces, in the ChessBoard.
In your Initialize method:
Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(*pPiece);
There are a couple of problems. One, you are pushing back a sliced copy of the Piece, which will be fixed when you change your vector to store pointers. Second, if you just change this like so:
Piece *pPiece;
// ...
Pawn pPawn(&pos,"blue",'P');
pPiece = &pPawn;
vPieceSet.push_back(pPiece); // <-- not dereferencing
You will have a new problem because you'll be storing the pointer to a local (automatic) variable. Best is to do this:
Piece* pPiece = new Pawn (...);
// ...
vPieceSet.push_back (pPiece);
Please don't forget to delete everything you new. This is best handled by using smart pointers rather than raw pointers. In C++03 we have auto_ptr, but those can't go in a vector. Instead you'll need to use Boost or something else, or just store raw pointers. In C++11, we now have unique_ptr (preferred) and shared_ptr, which can go in to a vector.
In C++11, the best solution here is to have a vector declared as:
vector <unique_ptr <Piece> > pPieceSet;
...unless you have some compelling need to use shared_ptr instead.
As others have mentioned, it is a slicing issue, and the issue is created here:
class Player
{
private:
std::string pName;
std::vector<Piece> vPieceSet; // <-- This is your problem
int turn;
public:
Player(int turn);
~Player();
void Initialize();
std::string GetName();
void SetName(std::string Name);
int GetTurn();
std::vector<Piece>* GetPieces();
};
You are storing them in the vector as instances of Piece, which is slicing off the details of the piece (e.g. the Bishop implementation). You should modify it to something like:
class Player
{
private:
std::string pName;
std::vector<Piece*> vPieceSet; // or better, use a smart pointer wrapper
int turn;
public:
Player(int turn);
~Player();
void Initialize();
std::string GetName();
void SetName(std::string Name);
int GetTurn();
std::vector<Piece*> GetPieces(); // note this change as well
};
With your additional question/edit, you are getting another unrelated problem:
void Player::Initialize() //Initial and final ranges for position
{
Position pos; // position is declared inside the scope of Initialize
Piece *pPiece;
if( this->turn == 0 )
{
this->SetName("Player 1");
for( int i=8;i<16;i++ )
{
pos.SetPosition(i);
Pawn pPawn(&pos,"blue",'P'); // you are passing the address of position to the Pawn, and Pawn is within the scope of this loop
pPiece = &pPawn; // you are storing the address of the Pawn
this->vPieceSet->push_back(pPiece);
}
// Pawn is now out of scope and pPiece points to the memory location Pawn *used* to be at (but will likely be overwritten soon).
// As soon as this function returns, you have the same problem with pos
}
You need to allocate those variables on the heap (hence the reason we suggested smart pointer wrappers).