Understanding Abstraction in C++ - c++

Coming from Java to C++ I'm attempting to understand abstraction through object orientation.
To put this into a practical example, I am developing a small game using the SFML library for graphics. However this question does not relate to that, simply think of it as background info. Anyway, the way the game works is to process through a number of different states. In this case 2:
The Menu State: The menu of the game is drawn and the game will begin here.
The Game State: This state controls the game, will update entities and draw them.
In order to do this I have created the following classes:
GameStateManager.h
#ifndef GAMESTATEMANAGER_H
#define GAMESTATEMANAGER_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "GameState.h"
class GameStateManager
{
public:
// Constructor
GameStateManager();
// State variables
static const int NUMGAMESTATES = 2;
static const int MENUSTATE = 0;
static const int GAMESTATE = 1;
// Public Functions
void set_state(int state);
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
// Array of gamestates
GameState game_states[];
// The current state
int current_state;
// Private functions
void load_state(int state);
void unload_state(int state);
};
#endif
GameState.h
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <iostream>
#include <SFML/Graphics.hpp>
#include "GameStateManager.h"
class GameState
{
protected:
GameStateManager gsm;
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void draw(sf::RenderWindow &win) = 0;
virtual void input(sf::Event event) = 0;
};
#endif
Now you may have noticed the Array of GameStates in Game State Manager? This provides an error to which I do not understand: zero-sized array. Does this mean initialization needs to be made within the header file? Further to this point the compiler mentions an Array of Abstract class isn't allowed?
The second issue is that the field gsm in the abstract GameState class does not recognize and brings up yet another error: Missing type specifier.
Now to complicate things further I have the following class: MenuState. This class is meant to extend GameState.
MenuState.h
#ifndef MENUSTATE_H
#define MENUSTATE_H
#include "GameState.h"
class MenuState: public GameState
{
public:
MenuState(GameStateManager gsm);
void init();
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
sf::Texture title_texture;
sf::Sprite title_sprite;
};
#endif
As mentioned this class will control the menu of the game.
Implementing GameStateManager is done as follows:
GameStateManager.cpp
/*
* GameState Manager will take care of the various states of the game.
* In particular there will be two states: Menu or Ingame. GameStateManager
* will load and unload each state as needed.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "GameStateManager.h"
// Class Constructor
GameStateManager::GameStateManager()
{
game_states = game_states[NUMGAMESTATES];
current_state = MENUSTATE;
load_state(current_state);
}
/*
* Load the current game by creating and initialising the state
* then storing it in the game_states array.
* #Param state The state we wish to load.
*/
void GameStateManager::load_state(int state)
{
if(state == MENUSTATE)
game_states[state] = MenuState(this);
//if(state == GAMESTATE)
//game_states[state] = MainGameState(this); // Not implemented yet.
}
/*
* Unload the state we loaded with load_state
*/
void GameStateManager::unload_state(int state)
{
game_states[state] = NULL;
}
void GameStateManager::set_state(int state)
{
unload_state(state);
current_state = state;
load_state(state);
}
void GameStateManager::update()
{
try{
game_states[current_state].update();
}
catch(int e)
{
std::cout << "Exception occured during update of game state" << e << std::endl;
}
}
void GameStateManager::draw(sf::RenderWindow &win)
{
try{
game_states[current_state].draw(&win);
}
catch(int e)
{
std::cout << "Exception occured when trying to draw gamestate: " << current_state << "Exception number: " << e << std::endl;
}
}
void GameStateManager::input(sf::Event event)
{
game_states[current_state].input(event);
}
And MenuState as follows:
/*
* This class extends the Game State header and will deal with the menu of the game
* this includes drawing the correct text to the screen, moving the selector and
* either exiting, bringing up about or starting the game.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "MenuState.h"
MenuState::MenuState(GameStateManager gsm)
{
gsm = gsm;
init();
}
void MenuState::init()
{
title_texture = sf::Texture();
title_texture.loadFromFile("sprites/Title.png");
title_sprite = sf::Sprite();
title_sprite.setTexture(title_texture);
title_sprite.setPosition(512, 200);
}
void MenuState::update(){}
void MenuState::draw(sf::RenderWindow &win)
{
win.draw(title_sprite);
}
void MenuState::input(sf::Event event)
{
}
Please ignore inplemented methods and positionings. At this point I began to attempt to compile the project (I'm using Visual Studio) when the errors appeared.
Now in understand that the MainGameState hasn't been implemented yet but even with MenuState I'm sure I'm missing something vital here as I am still learning C++. With this in mind also please excuse any breakage of conventions etc again I am learning so feel free to correct me, it is better I learn the right way now rather than develop bad habits.
In Summary I'd like to understand why I am receiving the following errors:
protected:
GameStateManager gsm;
This produces the error: missing ';' before gsm.
GameState game_states[];
Produces the errors of: zero-size array, array of abstract class not allowed.
I believe if I fix these the rest will sort themselves out.
Thank you for your patience, time and assistance with this.
Euden

To be short: you don't know any basics of C++, and as a beginner, you should really aproach it as a totally different language than Java or C, so you should stop your project right now and find a good book for C++ beginners. Don't try to mix your Java knowledge and just fill the gaps to reach C++ knowledge, it will not work because even if the syntaxe is close, they are widely different beasts.
I always recommend learning C++ as a new and different language, whatever your background. Right now you are doing big errors that shows you're on the wrong path to learn C++. You should get back to basic tutorials (I'm not trying to be harsh, you really need to learn the basics before even managing to compile this code).
You use of arrays and members like if they were references shows your lack of understanding of "value semantic" and several other basic concepts which are must-known of C++ usage.
For example, if I have
class A
{
int k = 42; // C++11
};
Here a A object will contain a k object. What I mean is that k is not a pointer to an int, it's the actual value, within memory allocated into the A object.
So if I have
A my_object; // object on the stack
Then my_object is an object taking the size of an int. So if I do:
class B
{
int u;
A a;
};
Then an instance of B will actually be the size of a A object, plus the size of an int. B objects will contain all these data in a single block of memory.
So when you do:
class GameState
{
protected:
GameStateManager gsm;
What you actually do here is that you build a full GameStateManager into any GameState object. Yes, gsm is not a reference, it's the full object.
What you should do here is either use a c++ reference (if the game manager should never change) or use a pointer (or a smart poitner if there is ownership involved).
I see a lot of other problems, like your array member into GameStateManager have absolutely not the same meaning than in Java. Basically, you're note coding in C++ here. (and you should use either std::vector or std::array but your GameState are dynamic so it would vector or array of pointers - or even map or another container).
As there is too much to point, I should get to the core point:
Whatever the language that you have learnt before, even C or Java which are related, never ever assume you know anything of C++ yet, you absolutely don't. You need to approach it as a beginner. Learn it as a very new language.
And make sure you read actually good material as the list provided there. It's extremely easy to learn bad practice online about C++, unfortunately (but it gets better).
Also, you might want to read this: https://softwareengineering.stackexchange.com/questions/76675/how-can-a-java-programmer-make-the-most-of-a-new-project-in-c-or-c/76695#76695
By the way, a related recommendation: read "SFML Game Development" book for example of simpler and safer (and C++-idiomatic) ways to do what you are trying to achieve here.
Another side recommendation would be to avoid using "manager" in your type names, it only makes things hard to understand and design.

The "zero-size array" error is caused by GameState game_states[];.
In C++ you have to specify the array size at declaration time, either by specifically writing the size or direct initializing it.
Example:
GameState game_states[ ]; // Error, compiler can't know how much memory to reserve for this.
GameState game_states[4]; // OK, explicit size given, compiler will reserve enough memory for 4 `GameState` objects.
GameState game_states[ ] = { GameState( ), GameState( ) }; // OK, direct initialization, compiler will reserve enough memory for 2 `GameState` object.
In your case it should be:
GameState game_states[ NUMGAMESTATES ];
And you should drop the following line from GameStateManager constructor:
game_states = game_states[NUMGAMESTATES]; // Meaningless in C++.
"Array of Abstract class isn't allowed" arises from this declaration also, the problem is C++ differs from Java here. In C++ this declares a variable which is a GameState instance, which is not allowed because GameState has pure virtual methods and as so can't be instantiated ( Just as Java abstract classes can't be newed ). To achieve this polymorphic behavior in C++ you have to use pointers or references, which is what Java uses implicit for you.
Fixing this should give you:
GameState * game_states[ NUMGAMESTATES ];
"missing ';' before gsm" is happening just because the compiler couldn't compile GameStateManager, fixing the bugs I mentioned should solve this.
Few tips:
Think of variables in C++ as ints from Java, even for types you've declared yourself. Which means they are instantiated just by declaring then ( no new needed ) and they are copied when assigned to another variable. ( no reference semantics by default as Java )
Look for good C++ books/tutorials as you don't seem to understand some very important basic concepts from C++.

Related

How can I properly initialize C++ objects within an Arduino program?

In my simple Arduino project, in order to keep things tidy, I decided to create a "Mode Manager" that will handle passing between one mode and another. The basic concept is that each time I want to change the mode, then it will instantiate the next mode and replace the previous one.
Please note that I have 12+ years experience in OOP and Java / Scala, but no experience whatsoever in C++, just the stuff needed to make an Arduino do its stuff without too many structures.
With some studying I managed to create the following "interface" structure:
File: modes/ModeManager.h. This should keep a reference to the current mode, and delegate to it the looping and instantiating the next mode (each mode will know which is the next in line)
#ifndef __MODE_MANAGER__
#define __MODE_MANAGER__
#include <stdint.h>
#include "modes/Mode.h"
class ModeManager {
private:
Mode *mode;
public:
ModeManager();
~ModeManager() {};
virtual void loop(uint8_t voltage);
};
#endif
File: modes/Mode.h is the actual "mode" that runs the real loop function of the program. It also handles instantiating the next mode
#ifndef __MODE__
#define __MODE__
#include <stdint.h>
class Mode {
public:
Mode() {}
virtual ~Mode() {}
virtual void loop(uint8_t voltage) = 0;
virtual void getNext(Mode * target) = 0;
};
#endif
File: modes/ModeManager.cpp
#include "ModeManager.h"
#include <stdint.h>
#include <Arduino.h>
#include "modes/Mode.h"
#include "modes/DummyMode.h"
#define VOLTAGE_NEXT_MODE 5
ModeManager::ModeManager() {
DummyMode cmode = DummyMode();
mode = & cmode; // I'm not sure how this should actually be done
}
void ModeManager::loop(uint8_t voltage) {
if (voltage == VOLTAGE_NEXT_MODE) {
Serial.println("Switching to next mode");
mode->getNext(mode);
} else {
Serial.println("Calling mode loop");
mode->loop(voltage); // From here, nothing.
}
}
File: modes/DummyMode.h
#ifndef __DUMMY_MODE__
#define __DUMMY_MODE__
#include "modes/Mode.h"
class DummyMode : public Mode {
public:
DummyMode();
~DummyMode() {}
virtual void loop(uint8_t voltage);
virtual void getNext(Mode * target);
};
#endif
File: modes/DummyMode.cpp
#include "modes/DummyMode.h"
#include <Arduino.h>
DummyMode::DummyMode() {
Serial.println("Initialization of dummy mode");
}
void DummyMode::loop(uint8_t voltage) {
Serial.print("Voltage: ");
Serial.println(voltage);
}
void DummyMode::getNext(Mode * target) {
DummyMode nextMode = DummyMode();
target = &nextMode;
}
and finally my main.cpp
#include <Arduino.h>
#include "modes/ModeManager.h"
#include "modules/memory.h"
#include "modules/monitor.h"
ModeManager * modeManager;
void setup() {
pinMode(A0, INPUT);
Serial.begin(9600);
Serial.println("Init");
ModeManager mm = ModeManager();
modeManager = & mm;
}
void loop(void) {
uint8_t voltage = map(analogRead(A0), 0, 1024, 0, 5);
modeManager->loop(voltage);
}
Now, theoretically I see no reason why this should not work. In practice I'm 99.9% sure I am doing something wrong with initializations and pointers.
When I try to run this code, I get the following serial out:
Init
Initialization of dummy mode
Calling mode loop
Which means that it freezes at the first iteration of the loop, right before calling mode->loop(voltage);
Can anyone point me in the right direction? Again, I have really no experience of C++, and my knowledge of how to make this structure came from various online resources of C++ programming, including some answers here so please bear with me
Here:
DummyMode cmode = DummyMode();
you are creating a DummyMode instance cmode with automatic lifetime (commonly referred to as on the stack).
You then take the address and assign that to another variable:
mode = & cmode; // I'm not sure how this should actually be done
Since cmode is an object with automatic lifetime it will be destroyed when the program leaves the scope in which it was created. As a result the pointer stored in mode will be dangling and referring to an object that no longer exists. Dereferencing it will trigger undefined behaviour.
It looks like your intention is to create the object with dynamic lifetime.
You can do that with the following:
mode = new DummyMode();
Though then you are responsible for ensure the object is destroyed when it is no longer needed.
That would be done with delete:
delete mode;
In more idiomatic/modern C++ it is typically to use smart pointers to manage the lifetime of such objects and not manually call delete. I see that C++'s standard library is not available for Arduino, but there does seem to be a smart pointer available: https://www.arduino.cc/reference/en/libraries/arxsmartptr/
I would recommend having a good look at using that to have a much easier time avoiding memory leaks.

C++ object method calling methods from another class that includes it's

First of all, sorry for the title. I didn't know exactly how to give name to the situation I'm facing.
I am developing a project in C++ that will run over QNX (so answers that recur to Windows libraries are not good).
I have one class that holds and manipulates all my data, and a few other classes that are responsible for dealing with my UI.
The UI manipulating classes include my data class, and when they are initialized, they all get a pointer to the same data object (each one uses different parts of it, though). And the normal flow of the program is the UI receiving events from the user, and then making calls to the data class and updating itself, according to the data class replies. That all works just fine.
The problem is, sometimes it might happen that this data class object receives calls from other sorts of external events (let's say a call from a class responsible for communication), asking it to change some of it's values. After doing so, it would have to update the UI (thus, having to make a call to the UI classes).
The actual objects to all the classes (UI and data) are contained by the "main" class. But as the UI classes include the data class to be able to call it's methods, the data class including UI classes in order to be able to call their methods would fall into mutual inclusion.
The problem resumes, in a very simplistic way (I am just trying to give a visual example of the information flow), to something like this:
main.cpp
#include "interface.h"
#include "data.h"
Data data_;
Interface interface_;
// Initialize all data from files, etc
data_.Init();
// Call the interface that will use all of this data
interface_.Init(&data_);
while(1);
interface.h
#include "data.h"
class Interface
{
Data *data_;
void Init(Data *data);
void ReceiveEvent();
void ChangeScreen (int value);
};
interface.cpp
#include "interface.h"
void Interface::Init(Data *data)
{
// Get the pointer locally
data_ = data;
}
// Function called when a (for example) a touch screen input is triggered
void Interface::ReceiveEvent()
{
ChangeScreen(data_->IncreaseParam1());
}
void Interface::ChangeScreen (int value);
{
// Set the value on screen
}
data.h
class Data
{
int param 1;
void Init();
int IncreaseParam1();
void ReceiveExternalEvent();
};
**data.cpp"
#include "data.h"
void Data::Init()
{
// The value actually come from file, but this is enough for my example
param1 = 5;
}
int IncreaseParam1()
{
param1 += 5;
return param1;
}
// This is called from (for example) a communication class that has a
// pointer to the same object that the interface class object has
void ReceiveExternalEvent()
{
IncreaseParam1();
// NOW HERE IT WOULD HAVE TO CALL A METHOD TO UPDATE THE INTERFACE
// WITH THE NEW PARAM1 VALUE!
}
I hope I made myself clear enough.
Can someone please give me ideas on how to deal with this situation?
Thanks a lot in advance!
Both Data and Interface are singletons. You expect to only have one instance of each class in existence. So:
Class Data {
public:
static Data *instance;
Data()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Class Interface {
public:
static Interface *instance;
Interface()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Now, ReceiveExternalEvent() will simply invoke Data::instance->method() and/or Interface::instance->method(), and so on...
This is a classical singleton design pattern.
Also, you might find some additional Google food of likely interest to you: "model view controller" and "mvc".

Cast relatives classes to each other which has common parent class

I have classes DBGameAction and ServerGameAction which has common parent class GameAction. Classes DBGameAction and ServerGameAction it's a API for safety working with entity GameAction from different part of program.
My question is: is it normal at first create DBGameAction entity and then cast it to the ServerGameAction entity? Or maybe it's a wrong program design?
My program:
#include <vector>
#include <string>
#include <iostream>
class GameAction
{
protected:
/* Need use mutex or something else for having safety access to this entity */
unsigned int cost;
unsigned int id;
std::vector<std::string> players;
GameAction(){}
public:
unsigned int getCost() const
{
return cost;
}
};
class DBGameAction : public GameAction
{
public:
void setCost(unsigned int c)
{
cost = c;
}
void setId(unsigned int i)
{
id = i;
}
};
class ServerGameAction : public GameAction
{
ServerGameAction(){}
public:
void addPlayer(std::string p)
{
players.push_back(p);
}
std::string getLastPlayer() const
{
return players.back();
}
};
int main(int argc, char *argv[])
{
DBGameAction *dbga = 0;
ServerGameAction *sga = 0;
try {
dbga = new DBGameAction;
}
catch(...) /* Something happens wrong! */
{
return -1;
}
sga = reinterpret_cast<ServerGameAction*>(dbga);
sga->addPlayer("Max");
dbga->setCost(100);
std::cout << dbga->getCost() << std::endl;
std::cout << sga->getLastPlayer() << std::endl;
delete dbga;
sga = dbga = 0;
return 0;
}
It is wrong program design.
Is there a reason why you are not creating GameAction variables which you then downcast to DBGameAction and ServerGameAction?
I haven't used reinterpret_cast in many occasions but I am sure it shouldn't be used this way. You should try to find a better design for the interface of your classes. Someone who uses your classes, doesn't have a way to know that he needs to do this sort of castings to add a player.
You have to ask yourself, if adding a player is an operation that only makes sense for ServerGameActions or for DBGameActions too. If it makes sense to add players to DBGameActions, then AddPlayer should be in the interface of DBGameAction too. Then you will not need these casts. Taking it one step further, if it is an operation that makes sense for every possible GameAction you may ever have, you can put it in the interface of the base class.
I have used a similar pattern effectively in the past, but it is a little different than most interface class setups. Instead of having a consistent interface that can trigger appropriate class-specific methods for accomplishing similar tasks on different data types, this provides two completely different sets of functionality which each have their own interface, yet work on the same data layout.
The only reason I would pull out this design is for situations where the base class is data-only and shared between multiple libraries or executables. Then each lib or exe defines a child class which houses all the functionality that it's allowed to use on the base data. This way you can, for example, build your server executable with all kinds of nice extra functions for manipulating game data that the client isn't allowed to use, and the server-side functionality doesn't get built into the client executable. It's much easier for a game modder to trigger existing, dormant functionality than to write and inject their own.
The main part of your question about casting directly between the child classes is making us worry, though. If you find yourself wanting to do that, stop and rethink. You could theoretically get away with the cast as long as your classes stay non-virtual and the derived classes never add data members (the derived classes can't have any data for what you're trying to do anyway, due to object slicing), but it would be potentially dangerous and, most likely, less readable code. As #dspfnder was talking about, you would want to work with base classes for passing data around and down-cast on-demand to access functionality.
With all that said, there are many ways to isolate, restrict, or cull functionality. It may be worth reworking your design with functionality living in friend classes instead of child classes; that would require much less or no casting.

Is static casting a good design in my situation?

I use game state manager (intro, main menu, gameplay etc) from here. However there is one problem. A very minimalistic example:
class cApp //manages the states and gives them access to window
{
public:
cApp (RenderWindow & ref) : window(ref) {}
void changeState(cState *); //these function realy doesn't matter
void update();
void draw();
RenderWindow & window; //the same as in the article, this class not only manages state but gives them access to window etc
private:
std::vector <cState *> states;
}
The state:
class cState
{
public:
cState(cApp * ptr) : app(ptr) {}
virtual void update() = 0;
virtual void draw() = 0;
protected:
cApp * app;
}
So far everything is good. The problem is this is the part of basic framework. So the cApp is only very basic and gives access only to window. However there may be the case where the user wants to use networking in his game. Network engine isn't a part of single state so it must be at the more global (that means, cApp) level.
So the user does:
class cNetworkedApp : public cApp
{
public:
cNetworkedApp(RenderWindow & ref1, NetworkEngine & ref2)
: networking(ref2), cApp(ref1)
NetworkEngine & networking; //initialized in cNetworkedApp constructor
}
class CharacterCreationState : public cState
{
CharacterCreationState(cApp * ptr) : cState(ptr) {}
//implement pure virtual functions
void draw()
{}
void update()
{
//THE PROBLEM
//the state needs to access the network engine so casting is required
cNetworkedApp * ptr = static_cast<cNetworkedApp*>(app))
ptr->networking.sendSomething();
}
}
The only obvious solution is to include everything what may be possible in cApp, however as I said this is a framework. Of course some engines like physics engine or sound engine are things which you put into a state so that's not problem, but things like networking system must be the one object available for all states. And not every app uses it.
Do I need to redesign this code or is it okay?
Your cApp may keep with it a named list of a polymorphic type Engine, ie map<string,Engine*>, then, your user may ask the cApp if it has a given engine.
NetworkEngine would be a subclass of the pure abstract Engine.
Update
When dealing with a pointer that I you are sure that it is of the given specialized type, you should use static_cast, when you wanna query if the pointer can be casted to a type you should use dynamic_cast.
I, myself, have a safer approach for the first case, I use an assertion to guarantee that the type can be casted and use the static_cast in normal code:
Engine* fetchedEngine = cApp.fetch("network");
assert( dynamic_cast<NetworkEngine*>(fetchedEngine) != NULL );
NetworkEngine* network = static_cast<NetWorkEngine*>(fetchedEngine);
Only a object of type NetworkEngine should be putted on the "network" name, but maybe someone mistakenly put something else, the assert will make us safer without needing to worry about the overhead.

Vector Troubles in C++

I am currently working on a project that deals with a vector of objects of a People class. The program compiles and runs just fine, but when I use the debugger it dies when trying to do anything with the PersonWrangler object. I currently have 3 different classes, one for the person, a personwrangler which handles all of the people collectively, and a game class that handles the game input and output.
Edit: My basic question is to understand why it is dying when it calls outputPeople. Also I would like to understand why my program works exactly as it should unless I use the debugger. The outputPeople function works the way I intended that way.
Edit 2: The callstack has 3 bad calls which are:
std::vector >::begin(this=0xbaadf00d)
std::vector >::size(this=0xbaadf00d)
PersonWrangler::outputPeople(this=0xbaadf00d)
Relevant code:
class Game
{
public:
Game();
void gameLoop();
void menu();
void setStatus(bool inputStatus);
bool getStatus();
PersonWrangler* hal;
private:
bool status;
};
which calls outputPeople where it promptly dies from a baadf00d error.
void Game::menu()
{
hal->outputPeople();
}
where hal is an object of PersonWrangler type
class PersonWrangler
{
public:
PersonWrangler(int inputStartingNum);
void outputPeople();
vector<Person*> peopleVector;
vector<Person*>::iterator personIterator;
int totalPeople;
};
and the outputPeople function is defined as
void PersonWrangler::outputPeople()
{
int totalConnections = 0;
cout << " Total People:" << peopleVector.size() << endl;
for (unsigned int i = 0;i < peopleVector.size();i++)
{
sort(peopleVector[i]->connectionsVector.begin(),peopleVector[i]->connectionsVector.end());
peopleVector[i]->connectionsVector.erase( unique (peopleVector[i]->connectionsVector.begin(),peopleVector[i]->connectionsVector.end()),peopleVector[i]->connectionsVector.end());
peopleVector[i]->outputPerson();
totalConnections+=peopleVector[i]->connectionsVector.size();
}
cout << "Total connections:" << totalConnections/2 << endl;
}
Where hal is initialized
Game::Game()
{
PersonWrangler* hal = new PersonWrangler(inputStartingNum);
}
0xBAADFOOD is a magic number to alert you to the fact that you're dealing with uninitialized memory. From the stack trace, we see that this in PersonWrangler::outputPeople is invalid. Thus hal doesn't point to a valid PersonWrangler (that is, assuming frame 4 is a call to Game::menu). To resolve this sort of thing yourself, step through the code, starting at Game::Game(), examining Game::hal as you go, to see what might be going wrong.
In Game::Game, hal is a local variable that shadows Game::hal. When Game::Game exits, this hal goes out of scope and leaks memory, while Game::hal remains uninitialized. What you want is:
Game::Game()
{
hal = new PersonWrangler(inputStartingNum);
}
Debuggers fill uninitialized memory with magic numbers to make it easier to spot errors. In a production build, memory isn't filled with anything in particular; the content of uninitialized memory is undefined, and might hold valid values. This is why a production build might not fail when a debug build will.
Did you initialize hal to point to an actual PersonWrangler object?
Creating a pointer does not point it at an actual object unless you do it explicitly. You probably want to either pass a PersonWrangler to your Game at construction time, or have the Game constructor create a PersonWrangler using new. If you choose the latter, make sure to delete your PersonWrangler somewhere, probably in the Game deconstructor.