C++ Object or 2-dimensional Array as a Parameter? - c++

In a Tic Tac Toe game I creating for school I have five classes: Game (acts as a controller for the game), Player (base class), HumanPlayer and AIPlayer (both derived from Player), and Board.
Board contains a 2D array and some functions for displaying and working on the array. All three player classes have a function makeAMove(Board &board) which will choose a position on the board and place an X or an O.
As you can see makeAMove accepts a Board object as a parameter. Then the function will decide on a move and alter the Board object's board array. If I'm understanding correctly, the actual object being passed in will be altered and there will not be any need to return anything back.
Am I understanding this correctly? Would it be better to use the 2d array as the parameter instead?
Here is a condensed version of my code.
#include <iostream>
#include <memory> // auto_ptr
class Board
{
public:
Board()
{
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
board[row][column] = ' ';
}
}
void displayBoard()
{
std::cout << "\n-------------" << std::endl;
for (int row = 0; row < 3; row++)
{
std::cout << "| " ;
for (int column = 0; column < 3; column++)
std::cout << board[row][column] << " | ";
std::cout << "\n-------------" << std::endl;
}
}
/* My thought was to use getBoard to return the array rather than using the
object as a parameter
char getBoard()
{
return board[][3];
}
*/
char getCell(int row, int column)
{
return board[row][column];
}
void setCell(int row, int column, char player)
{
board[row][column] = player;
}
private:
char board[3][3];
};
class Player
{
public:
virtual void makeAMove(Board &board) = 0;
};
class AIPlayer : public Player
{
virtual void makeAMove(Board &board)
{
// do some work ont the board array
}
};
class HumanPlayer : public Player
{
virtual void makeAMove(Board &board)
{
// do some work on the board array
}
};
class Game
{
public:
Game(unsigned int players)
{
if (players == 1)
{
player1.reset (new HumanPlayer());
player2.reset (new AIPlayer());
}
else
{
player1.reset (new HumanPlayer());
player2.reset (new HumanPlayer());
}
}
void playGame()
{
player1->makeAMove(myBoard);
}
private:
std::auto_ptr<Player> player1; // pointer to a Player object (C++11 has more secure unique_ptr)
std::auto_ptr<Player> player2; // pointer to a Player object
Board myBoard;
};
int main()
{
Game myGame(1);
myGame.playGame();
return 0;
}

Yes because you're passing the Board object by reference, any change to it in the function will alter the actual Board object. I think passing a Board object is a better idea, as it is better not to expose the actual implementation ( a 2D array in this case) of the game to the user. So passing as Board object gives more abstraction, which is good.

makeAMove belongs in board. The player objects should decide what move to make, then call board::makeAMove to make the move. That way the player objects don't care what the internal representation of the board is.

Pass the object by reference as you are instead of the array. Any alterations made by the player on the board will persist.
board is a private member of Board. It should only ever be returned by value and not by reference. If you pass the 2d array to the player by Value any changes they make to the board will not persist.
Your Player classes will need to access Board.setCell(int, int), in the makeAMove(Board &board) function and to do that they will need the board object.
However your Players classes will need to read the board. In order to make a move. The getCell(int,int) function might be enough but it might also be tedious to nested loop through all of the cells. A getBoard might be useful for a possible decideMove function.

Related

How to reset number of instances of a class to 1 on every loop iteration?

I have a player class where I am storing the player's current position, the number of players in the game and a static variable to store the total number of players like so:
#ifndef PLAYER_H
#define PLAYER_H
#include <ctime>
#include <random>
#include <iostream>
using std::time;
using std::cout;
class Player
{
private:
int m_Player_currentPosition, m_Player_number;
static int m_Player_numberOfPlayers;
public:
Player::Player():m_Player_currentPosition(1) {
m_Player_number = m_Player_numberOfPlayers;
++m_Player_numberOfPlayers;
}
void m_Player_SetPosition();
int m_Player_GetPosition();
int m_Player_GetPlayerNumber() { return m_Player_number; }
void m_Player_SetNumberOfPlayers() { m_Player_numberOfPlayers = 1; }
~Player() { --m_Player_numberOfPlayers; }
};
int Player::m_Player_numberOfPlayers = 1;
#endif
I also have a game class that creates a certain number of player instances using a vector. In my game class, the plan is to create players depending on user input (between 2-4 number of players) using m_Game_SetPlayers() member function and also printing the details of the players using the m_Game_PrintPlayers() member function.
#ifndef GAME_H
#define GAME_H
#include <iostream>
#include "Board.h"
#include "Player.h"
using std::cout;
using std::cin;
using std::vector;
class Game {
private:
bool m_Game_quit;
int m_Game_choice;
Board board;
vector<Player> m_Game_players;
public:
Game();
const bool &m_Game_GetQuit() const;
void m_Game_SetPlayers()
{
int numberOfPlayers = 2;
cout << "How many players (2-4)? ";
cin >> numberOfPlayers;
if (numberOfPlayers < 2 || numberOfPlayers > 4) {
numberOfPlayers = 2;
}
m_Game_players.resize(numberOfPlayers);
}
void m_Game_PrintMenu();
void m_Game_PrintInstructions();
void m_Game_GetChoice();
void m_Game_PrintPlayers()
{
cout << '\n';
vector<Player>::iterator iter;
for (iter = m_Game_players.begin(); iter != m_Game_players.end(); ++ iter) {
cout << "Player " << iter->m_Player_GetPlayerNumber() << "'s position: " << iter-
>m_Player_GetPosition() << '\n';
}
}
void Update();
};
#endif // !GAME_H
However, in my main class, I am calling the Game class's update function under a while loop. Here is my game update member function declared in a separate implementation file that decides the control flow of the game.
void Game::Update()
{
m_Game_GetChoice();
switch (m_Game_choice) {
case 0: cout << "---Bye---\n";
m_Game_quit = true;
break;
case 1:
system("cls");
m_Game_PrintInstructions();
break;
case 2:
system("cls");
m_Game_SetPlayers();
system("cls");
board.m_Board_PrintBoard();
m_Game_PrintPlayers();
m_Game_players[0].m_Player_SetNumberOfPlayers();
break;
default:
cout << "--Invalid Option---\n";
break;
}
}
Here is my while loop in the main function:
#include "Game.h"
int main() {
Game game;
while (!game.m_Game_GetQuit()) {
system("cls");
game.m_Game_PrintMenu();
game.Update();
system("pause");
}
}
When I ran this program the first time, it worked as expected. However, imagine if I choose the play option from the menu and I enter 2 players, it creates 2 instances of the player class. On the next while loop iteration, I increase the size to 4 players which also works perfectly sometimes. Then, when I reduce the size and then again increase the size, the player number does not match. Here are the following images to help understand the problem:
Input 1: https://i.stack.imgur.com/reHjE.png
Output 1: https://i.stack.imgur.com/Dt68V.png
Input 2: https://i.stack.imgur.com/Xo83c.png
Output 2: https://i.stack.imgur.com/2Qso6.png
The expected output is:
Player's position 1: 1
Player's position 2: 1
Player's position 3: 1
So, I thought that I need to delete my instances, but since I cannot delete instances on a stack memory as long as I am in a while loop (How do I manually delete an instance of a class?, http://www.cplusplus.com/forum/beginner/107822/). I thought that I will resize the vector. It did resize the vector, but then it does not delete the instances of the player class but instead created a new instance of that class. Is there a way to destroy all the instances of the class on a stack memory even when it is inside the scope? If not, how do I solve this problem?
I may/may not have provided the code needed to debug this problem. So, I have attached my entire code on https://github.com/F3INTH34RTED/Cpp/tree/master/Beginner/16SnakesAndLadder if need be.
When you increase the size of the vector, say from 2 to 3, it only needs to create one new instance of Player, so it will create a single player with the next number.
The line
m_Game_players[0].m_Player_SetNumberOfPlayers();
on the previous loop iteration sets the global counter to 1. So this single new player gets number 1, not number 3 like you expect. You should be able to remove the above line and things will work as expected.
On a design note, it would probably be wiser to recreate the vector entirely when the number of players is changed and explicitly give each player a number via the constructor, like this:
void m_Game_SetPlayers()
{
int numberOfPlayers = 2;
cout << "How many players (2-4)? ";
cin >> numberOfPlayers;
if (numberOfPlayers < 2 || numberOfPlayers > 4) {
numberOfPlayers = 2;
}
m_Game_players.clear();
for (int i = 1; i < numberOfPlayers; i++) {
m_Game_players.push_back(Player(i));
}
}
Updating the Player constructor to match, of course.
Your issue is that std::vector::push_back will do copy/move when it needs to resize internal buffer, and your (auto generated default) copy/move constructors doesn't handle that, you might do for example:
class Player
{
private:
int m_currentPosition;
std::optional<int> m_number;
static int m_numberOfPlayers;
public:
Player() : m_currentPosition(1), m_number(++m_numberOfPlayer) {}
Player(const Player&) = delete;
Player(Player&& rhs) : m_currentPosition(rhs.m_currentPosition), m_number(rhs.m_number) { rhs.m_number = std::nullopt; }
Player& operator = (const Player&) = delete;
Player& operator = (Player&& rhs) { std::swap(m_currentPosition, rhs.m_currentPosition); std::swap(m_number, rhs.m_number); }
int GetPlayerNumber() const { return *m_number; }
~Player() { if (m_number) --m_numberOfPlayers; }
};

How to use an array of pointers already filled as parameter of a function/method

I'm doing an Oriented Object Snakes & Ladders version. So I have a class called Game which have a method called startGame() and a method called play(). Here's the header of the class.
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
#include <iostream>
#include "Tiles.cpp"
class Game{
private:
int tiles, snakes, ladders, penalty, reward, players, turns, currentTurn;
char mode;
public:
Game();
Game(int, int, int, int, int, int, int, char);
void play(Tiles*, unsigned int);
void startGame();
};
#endif
So first I create an array of pointers of and added class named Tiles (which has 2 inherited classes: Snakes and Ladders) and I fill it with objects of those inherited classes.
void Game::startGame(){
int tiles, n1, n2, n3;
Tiles * board[tiles];
for (int i=0;i<n;i++){
board[i] = new Normal(i+1);
}
for (int i2=0;i2<n2;i2++){
do {
nTileS = rand() % tiles;
}while (board [nTileS] -> getType() != 'N');
board[nTileS] = new Snake(nTileS+1);
}
for (int i3=0;i3<n3;i3++){
do {
nTileL = rand() % tiles;
}while (board [nTileL] -> getType() != 'N');
board[nTileL] = new Ladder(nTileL+1);
}
Once I created the array, I call a function called play(), which has all the logic about the game but I want the array I created as a parameter. play(board[tiles], tiles);
void Game::play(Tiles* board, unsigned int nBoard){
cout<< "test" << endl;
for (int i=0; i<nBoard; i++){
board[i].showTile();//method that prints the info of the object, just for testing
}
But as a result, the code gives me only test, so actually the method works but apparently it doesn't recognize the objects of my array of pointers. I just want to know how to use that array of pointers in this case. Thank you by the way

2D Vector of Class Object Pointers C++

I'm attempting to create a dynamic 2D vector of class object pointers. I'm trying to make a randomized map for a text based game. I know there's solutions out there, but I want to hand build this puppy. I just.. suck at pointers.
I tried to create a 2D array of class pointers, but the syntax was quite difficult to follow. I don't really know where to begin. My last C++ class was a year ago and we only briefly went into vectors.
I've attempted to do some research on my own, but I just can't seem to blend the concepts together. I've been able to reference the following posts/pages:
Vector of Object Pointers, general help and confusion
http://www.cplusplus.com/doc/tutorial/pointers/
vector of class pointers initialization
https://www.geeksforgeeks.org/2d-vector-in-cpp-with-user-defined-size/
Right now, I'm on step one of my plan. I know once I get the 2D vector syntax down, the rest will fall into place. However, it's just not something I've ever done before. I'm sure my coding is not quite up to snuff for most, but it's been awhile...
If I may ask for clarification on the following, I think it would be a huge help to me.
1. How do you pass a 2D vector to a function by reference and what would the syntax be to manipulate the pointers held within properly?
2. How do you access class member functions of pointers within a 2D vector?
3. How do you dynamically create class objects that are pointed to by pointers in a 2D vector?
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <bits/stdc++.h>
using namespace std;
enum Dir{n, e, s, w};
class Object
{
private:
string objName;
public:
void setName(string n)
{
objName=n;
}
string getName() const
{
return objName;
}
Object()
{
objName="";
}
Object(string n)
{
objName=n;
}
virtual ~Object()
{
cout << "The " << objName << " was destroyed.\n";
}
};
class Room : public Object
{
private:
Room *north, *east, *south, *west;
public:
void setDir(Room *d, Dir a)
{
switch(a)
{
case n: north=d; break;
case e: east=d; break;
case s: south=d; break;
case w: west=d; break;
}
}
Room *getDir(Dir a)
{
switch(a)
{
case n: return north; break;
case e: return east; break;
case s: return south; break;
case w: return west; break;
}
}
Room(){}
Room(string rName, Room *n, Room *e, Room *s, Room *w) : Object(rName)
{
north=n;
east=e;
south=s;
west=w;
}
};
Room Wall;
void RoomRandomizer(vector<Room *> map, string rName)
{
int x=0, y=0, entX=0, extY=0;
bool entFound = false;
Room * tempRoom;
string rN = rName;
srand(time(NULL));
if(rName == "Entrance")
{
x=rand() % 7+1;
y=rand() % 5;
tempRoom = new Room(rName, &Wall, &Wall, &Wall, &Wall);
map[x][y]= tempRoom;
}
};
int main(){
int row=9, colom[]={9,9,9,9,9,9,9,9,9};
Wall.setName("Wall");
vector<vector<Room *>> map(row);
for (int i = 0; i < row; i++) {
// size of column
int col;
col = colom[i];
// declare the i-th row to size of column
map[i] = vector<Room *>(col);
//map.resize(9, vector<Room *>(9, 0));
}
map[0][0] = new Room("Entrance", Wall, Wall, Wall, Wall);
cout << map[0][0]->getName;
return 0;
}
Here is a short code examples.
// Passing in the vector of vectors by reference
void function(std::vector<std::vector<Room*>>& referece_to_2d_vector) {
// Call member function
Room* north = referece_to_2d_vector[0][0]->getDir(n);
// Just like you already do in main, dynamically allocating a new
// room and make one of the pointers point to it
referece_to_2d_vector[0][0] = new Room("New room", &Wall, &Wall, &Wall, &Wall);
// Is this what you mean when you say "manipulate the pointers held within" ?
referece_to_2d_vector[0][1] = north;
}
The first thing that comes to mind is that you should try to avoid using new if possible. You should look into maybe using std::unique_ptr and std::make_unique instead of raw pointers in the vector.
It is basically a pointer that also owns the object it points to, so when the pointer is destroyed you don't need to manually delete it.
std::vector<std::vector<std::unique_ptr<Room>>> map(1);
map[0].push_back( std::make_unique<Room>("Room1", &Wall, &Wall, &Wall, &Wall) );
map[0].push_back( std::make_unique<Room>("Room2", &Wall, &Wall, &Wall, &Wall) );
// You can get a raw pointer to the object owned by a `std::unique_ptr` with it's `get` function.
map[0][0]->setDir( map[0][1].get(), n);

Array without parameters in c++

I'm pretty new in c++ althought a bit experienced in java, and my problem it's the next one:
I'm doing a sudoku project where I'm creating an abstract data type of the box and the board. In the board one, I'm creating a bidimesional array of boxes, but when I want to create it as a public data so I can use it in the whole class and not only in the board constructor.
I'm creating it in the board constructor because If I don't create it there, I have no way of knowing the value of each dimension, and if I create the variable Box box[int][int] where I can use it in the class, I've got no way of knowing the dimensions. It'll be better understandable with some code.
This code allows me to create the Box array with the dimensions I want, because it's in the board constructor than when it's created it has as a parameters the number of boxes, but it don't let me use the "casilla" variable in the other part of the class nor other classes:
class tablero{
int filas;
int columnas;
public:
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
Casilla casilla[filas][columnas];
}
Casilla getCasilla(int n, int m){
return casilla[n][m]; <- Here shows an error because casilla cannot be resolved.
}
And this other code lets me use the casilla variable, but I have to give it the parameters to the dimensions before I know them:
class tablero{
int filas;
int columnas;
public:
Casilla casilla[0][0];
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
}
Casilla getCasilla(int n, int m){
return casilla[n][m];
}
No error, but the dimensions of the casilla array have to be given before I know them, and so, they may be the wrong ones (because the board may have different dimensions.
It's the first time I'm programming in c++, and I'm really frustated with this problem, can anyone help me to find a way to make it so it works both ways? (I already tried to leave both dimensions empty and then in the constructor put casilla[][] = Casilla cas[filas] [columnas] but it gives me an error..)
Thanks for the help everyone. Also, If you think the title is not clear enough, you can suggest one and I'll change it.
The Casilla code is this one:
class Casilla{
int fila;
int columna;
int numero;
public:
// constructor
Casilla(int fila, int columna,int numero)
{
this->fila = fila;
this->columna = columna;
this->numero = numero;
}
};
Thanks everyone for your answers, I've already found the answer I needed from 3 different people. I can't upvote all of you because I still don't have 15 reputation, but when I have it i'll upvote you all. Thanks for all your answers, really. I just need to know what I commented on the checked answer and it'll be all answered.
A solution with an array
//----------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
//----------------------------------------------------------------------------
class Casilla
{
int fila;
int columna;
int numero;
public:
// default constructor
Casilla()
{
this->fila = -1;
this->columna = -1;
this->numero = 0;
}
int GetNumero() {return numero;}
void SetCasilla (int _fila, int _columna) //set a cell position
{
fila = _fila;
columna = _columna;
}
void SetCasilla (int _numero) //set a cell value
{
numero = _numero;
}
void SetCasilla (int _fila, int _columna, int _numero) //set a cell position and value
{
fila = _fila;
columna = _columna;
numero = _numero;
}
};
class Tablero
{
int filas;
int columnas;
Casilla **casilla;
public:
Tablero (int filas, int columnas)
{
this->filas = filas;
this->columnas =columnas;
casilla = new Casilla* [filas];
for (int i = 0; i<filas; i++)
casilla[i] = new Casilla [columnas];
for (int i = 0; i<filas; i++)
for (int j = 0; j<columnas; j++)
casilla[i][j].SetCasilla(i,j); //set the right position for each cell
//the values = 0 by default
}
//destructor
~Tablero()
{
for (int i = 0; i<filas; i++)
delete [] casilla[i];
delete [] casilla;
}
//set a cell value in the table
void ChangeCasillaValue (int _fila, int _columna, int _numero)
{
casilla[_fila][_columna].SetCasilla (_numero);
}
Casilla getCasilla(int n, int m)
{
return casilla[n][m];
}
void PrintTablero ()
{
for (int i = 0; i<filas; i++)
{
for (int j = 0; j<columnas; j++)
std::cout << std::setw(5)<<casilla[i][j].GetNumero();
std::cout << "\n";
}
std::cout << "\n";
}
};
//----------------------------------------------------------------------------
int main()
{
int N = 5, M = 6;
Tablero table(N, M);
table.PrintTablero();
table.ChangeCasillaValue(1,1,-5); //change value in cell(1,1)
table.PrintTablero();
std::cin.get();
return 0;
}
//-----------------------------------------------------------------------------
You have to add a bunch of setters and getters of your own.
But, as a draft, it works.
C-style array dimensions must be known at compile-time in C++. So there is no variant of Casilla casilla[filas][columnas]; that will work.
Instead you should use a container which can hold the data you want to put in it. Use of C-style arrays in C++ is discouraged because they have some strange behaviour and rules, they are mainly there for backwards compatibility.
The simplest option is a 1-dimensional array with runtime size, that is called vector:
class tablero{
int filas;
int columnas;
std::vector<Casilla> casilla;
public:
tablero (int filas, int columnas)
: filas(filas), columnas(columnas), casilla(filas * columnas)
{ }
Casilla getCasilla(int f, int c) const
{
return casilla[f * columnas + c];
}
};
Note the use of the constructor initializer list. You should provide initial values for class members this way, instead of using assignment statements inside the constructor.
In your first example, in your constructor, the line
Casilla casilla[filas][columnas];
declares casilla an array of arrays of Casilla objects local to your constructor. Once your constructor returns, casilla goes out of scope. There is no casilla member variable or local variable in your getCasilla function, so of course it cannot be resolved.
In your second example, your class has a public member casilla declared as 0 by 0 array of Casilla objects. Your getCasilla function would return the item in the nth row and mth column of the 0 by 0 array. In C++, there is no bound checking on array dereferences, so this is returning some out of bounds memory location and is very bad.
You can create dynamic C arrays yourself by using malloc and free, but since you are using C++ it will be easier to just use std::vector.
For example, you could use:
#include <iostream>
#include <vector>
class Casilla
{};
class tablero
{
int filas_;
int columnas_;
std::vector<std::vector<Casilla> > casilla_; // a vector of vectors of Casillas
public:
tablero(int filas, int columnas) : filas_(filas), columnas_(columnas),
casilla_(filas, std::vector<Casilla>(columnas))
// The above is an initialization list
// We initialize casilla_ as a vector of filas vectors of columnas Casillas
{}
std::vector<std::vector<Casilla> > getCasilla() const
{
return casilla_;
}
};
int main(int argc, const char* argv[])
{
tablero t(3, 3);
std::cout << "casilla rows: " << t.getCasilla().size() << std::endl;
std::cout << "casilla cols: " << t.getCasilla()[0].size() << std::endl;
return 0;
}
First Casilla casilla[filas][columnas]; needs to be a class variable so it's accessible to all methods.
Second the sizes of rows and columns must be a fixed number e.g Casilla casilla[9][9];
If it need to be dynamically allocated you could you Vectors or Vectors of Vectors.
If it's 2d array, you can still create it as 1d array, but depends which is best for your purposes.

Passing struct between functions C ++

I've searched but haven't been able to get what I want...
I'm doing a little game. And I got this struct that contains the player details.
struct Player
{
string name;
int level;
int exp;
int hp; // life
int mp; // mana
int shield;
};
And when in the menu, the user chooses to start a new game, it goes to this function:
int StartNewPlayer(string name)
{
Player player;
player.name = name;
player.level = 1;
player.exp = 0;
player.hp = 20;
player.mp = 5;
player.shield = 0;
*pass/return the struct here*
}
Then I have a function that prints the game board, and where I should use the data from the new player struct, for example:
void game_board ()
{
cout << "Hello!" << player.name;
(...)
}
Finally, somewhere in main I have:
int main ()
{
StartNewPlayer(new_game());
game_board();
}
that calls all the functions above.
But I can't figure it out... I tried references, pointers without luck.. I need some help here please...
How about this?
Player StartNewPlayer(string name)
{
Player player;
player.name = name;
player.level = 1;
player.exp = 0;
player.hp = 20;
player.mp = 5;
player.shield = 0;
return player;
}
void game_board(Player player)
{
cout << "Hello!" << player.name;
(...)
}
int main ()
{
Player player = StartNewPlayer(new_game());
game_board(player);
}
Do not create extra copies of the data with complex datatypes by using pass-by-value
Use pointers instead to pass the address of the variable that can be modified in the function. The changes will be reflected in the caller's function as well.
void StartNewPlayer(string name, Player *player)
{
player->name = name;
player->level = 1;
player->exp = 0;
player->hp = 20;
player->mp = 5;
player->shield = 0;
}
void game_board(Player* player)
{
cout << "Hello!" << player->name;
(...)
}
int main ()
{
Player player;
StartNewPlayer(new_game(), &player);
game_board(&player);
}
Alternative using pass-by-reference:
If you're a fan of references, (which is just a clever compiler-trick that makes use of pointers internally again):
void StartNewPlayer(string name, Player& player)
{
player.name = name;
player.level = 1;
player.exp = 0;
player.hp = 20;
player.mp = 5;
player.shield = 0;
}
void game_board(Player& player)
{
cout << "Hello!" << player.name;
(...)
}
int main ()
{
Player player;
StartNewPlayer(new_game(), player);
game_board(player);
}
I would suggest returning a pointer to a Player struct. If you return a "reference" like you are doing right now, it will call the copy constructor of Player which can lead to further complications.
Normally, at the end of StartNewPlayer(...), the Player you declared there will cease to exist as the object scope will end, so when you return it, the c++ compiler gets that you want to keep the object alive and will create a copy for you, invisibly. If you return a pointer to it, you really are returning the object you allocated in your function.
Suppose that you have pointers in your Player structure, such as
struct Player
{
int level;
char* name; //lets assume you did it like that
}
When you are returning the Player, the int will be copied, but the char* will not. ints are easy to handle while char* need all kind of tricky functions like strlen and strncpy. The more complex your Player struct becomes, the more problem you will face by using the default copy constructor.
Another solution would be to declare a copy constructor yourself for the Player struct ( really, you could use classes since they are mostly interchangeable in c++ ).
Player(const Player& p)
{
name = p.name;
level = p.level;
// and so forth
}
So I would use
Player* StartNewPlayer(std::string name)
{
Player* player = new Player();
player->name = name;
player->level = 1;
// snip
return player;
}
At the end of your program, be sure to delete player otherwise you will have a memory leak