What should i do here?

Pages: 12
ok, so if i create a function outside the class like i create a save and load function then i dont need to put the prototyps in the class. I was looking over doom source code and i seen they put prototypes in the classes but this game was written in C so idk if thats just what C programmers did or what

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class idSysLocal : public idSys {
public:
	virtual void			DebugPrintf( const char *fmt, ... )id_attribute((format(printf,2,3)));
	virtual void			DebugVPrintf( const char *fmt, va_list arg );

	virtual double			GetClockTicks( void );
	virtual double			ClockTicksPerSecond( void );
	virtual cpuid_t			GetProcessorId( void );
	virtual const char *	GetProcessorString( void );
	virtual const char *	FPU_GetState( void );
	virtual bool			FPU_StackIsEmpty( void );
	virtual void			FPU_SetFTZ( bool enable );
	virtual void			FPU_SetDAZ( bool enable );

	virtual void			FPU_EnableExceptions( int exceptions );

	virtual void			GetCallStack( address_t *callStack, const int callStackSize );
	virtual const char *	GetCallStackStr( const address_t *callStack, const int callStackSize );
	virtual const char *	GetCallStackCurStr( int depth );
	virtual void			ShutdownSymbols( void );

	virtual bool			LockMemory( void *ptr, int bytes );
	virtual bool			UnlockMemory( void *ptr, int bytes );

	virtual int				DLL_Load( const char *dllName );
	virtual void *			DLL_GetProcAddress( int dllHandle, const char *procName );
	virtual void			DLL_Unload( int dllHandle );
	virtual void			DLL_GetFileName( const char *baseName, char *dllName, int maxLength );

	virtual sysEvent_t		GenerateMouseButtonEvent( int button, bool down );
	virtual sysEvent_t		GenerateMouseMoveEvent( int deltax, int deltay );

	virtual void			OpenURL( const char *url, bool quit );
	virtual void			StartProcess( const char *exeName, bool quit );
};


so if i create a member function then if i use it outside the class i would do Player::doSomething???

i just dont get why not putting function prototypes in a class would make it easier, because if a function need to use provate variables fdrom the class you can just do

Player::function()
{
variable = 60;
}

instead of

function()
{
Player p;
p.variable = 60;
}

every single time you want to access a classes variable
That is most definitely not C. C has no OOP (like class, virtual, public, inheritance, etc.). But it does have some C style to it.

Why not put everything in classes? Because they wouldn't make sense to call, and they violate encapsulation. Imagine a Bank class where every single function that uses it has access to the vault. Who knows how much money could be discreetly lost.

Plus, member functions usually need access to *this. Functions that can just use the interface of the class probably don't need to be members.

Why don't you show us this function you keep talking about that takes three or four class types as arguments?
Last edited on
here is my code,

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "Player_Class.h"
#include "Bank_Class.h"
#include "Customer_Class.h"
#include "Prototypes.h"

using namespace std;

int main()
{

    return 0;
}



Bank_Class.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef BANK_CLASS_H_INCLUDED
#define BANK_CLASS_H_INCLUDED

class Bank
{
    public:
        Bank();
        ~Bank();

    private:
        int moneyInVault;
};

#endif // BANK_CLASS_H_INCLUDED 


Customer_Class.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef CUSTOMER_CLASS_H_INCLUDED
#define CUSTOMER_CLASS_H_INCLUDED

#include <vector>

class Customer
{
    public:
        Customer();
        ~Customer();

    private:
        int customersMoney;
        std::vector<std::string> customerNames;
};

#endif // CUSTOMER_CLASS_H_INCLUDED 



Player_Class.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef PLAYER_CLASS_H_INCLUDED
#define PLAYER_CLASS_H_INCLUDED

class Player
{
    public:
        Player();
        ~Player();
        SaveGame();
        LoadGame();
        
    private:
        int playersMoney;
        int playerExperience;

        std::string playersName;
};

#endif // PLAYER_CLASS_H_INCLUDED 


Save_And_Load.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
#include <fstream>

void SaveGame()
{

}

void LoadGame()
{

}


see how save and load are in player class? that way when i need to save i can just do

Player::SaveGame() and i dont need to do any other accessing to the variables.
Last edited on
Lines 9 and 10 in the Player_Class header file are incorrect. If they are member functions, you forgot the return type, and if they are friends, you also forgot to prepend them with the friend keyword.

Now, I can understand why you'd want these two functions to access the private and protected variables. From your last post, however, you seem to think you need to create temporary objects (which would make no sense in the case of SaveGame) before doing anything.

As I have mentioned in one of my earlier post and have shown in my examples, pass the objects as parameters.
1
2
void SaveGame(const Player&, const Customer&, const Bank&);
void LoadGame(Player&, Customer&, Bank&);


Then use what member functions you provide to write your save data in SaveGame().
The member functions you'll be using in SaveGame() will probably be functions you'll also use in other parts of your program anyway. For example, displaying player experience and money, displaying how much money is in the bank, or displaying customer names.

LoadGame() especially has no need to access any of the data variables. It'd just read information from the file, convert it to the appropriate variable types, then pass it to the class constructor to create that state (which you haven't written yet).


Side Note:
I'm not sure if your Customer class should be holding a container of people when it sounds like it should be one person.
sorry i forgot the return type, but yes so if im going to do that and i want those functions to be able to access the variables in the classes i can just do this then?

1
2
void SaveGame(const Player&, const Customer&, const Bank&);
void LoadGame(Player&, Customer&, Bank&);


and put these in their own seperate .h file of course.

I find that putting variables in parameters is ubelievably annoying because when you create a new one you havde to put it in the parameter and the prototype and other places too and it just gets long and complicated but if i do it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class vars
{
    public:
        vars();
        ~vars();
        myFunction;
        
    private:
        int var1;
        int var2;
};

void vars::myFunction()
{
    var1 = 80;
    var2 = var1;
}



and see i dont need to put anything in the parameters, and thats what im trying to do but see if i have another class and i want to use variables from it in myFunction i cant because its already a member of vars class.
Last edited on
You add a new parameter, and you add in the new code in the implementation.
And add parameter to each call(many text editors come with a "replace" functionality to make this easier).
Independent of classes - More flexible.
vs.
Add code in the implementation. Make sure you include the proper headers or declare the correct classes. Make sure you don't tangle up your different classes. Figure out which class your functions should be a member of (or friend of).
Embedded into classes - Less flexible.

My point is that you shouldn't need to see the guts of your classes in order to use them, and your SaveGame and LoadGame functions especially have no need because they don't modify anything (well, LoadGame kind of).

Look at all you'd have to do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 const char delim(' '); //Could probably limit the scope of this to one file only
                        //   and could probably use a better delimiter

//I omitted some classes for the sake of brevity
void SaveGame(const Player& p, const Bank& b){
   std::ofstream saveState("save_state.dat");
   if(saveState.fail()) throw std::runtime_error("Unable to open save state file.");

   saveState
           << p.name() << delim
           << p.exp() << delim
           << p.money() << delim
           << b.money() << delim
   ;
   saveState.close();
}

void LoadGame(Player& p, Bank& b){
   std::ifstream saveState("save_state.dat");
   if(saveState.fail()) throw std::runtime_error("Unable to open save state file.");

   std::string p_name("");
   int p_exp(0), p_money(0);

      //Could probably refine below code
   saveState >> p_name >> p_exp >> p_money;
   if(saveState.good())
      p = Player(p_name, p_exp, p_money);
   else return;

   int b_money(0);
   saveState >> b_money;
   if(saveState.good())
      b = Bank(b_money);

   saveState.close();
}




Anyway, if you don't want to have parameters, you can have a Game Handler class to wrap around all the elements of your game. Then your SaveGame and LoadGame can be member functions of that wrapper (that take no parameters).
Last edited on
To expand on Daleth's response, you could create a Load and Save member of each class. That way, each class is responsible for loading and saving it's state. This has several advantages. It encourages data hiding and encapsulation (C++ strengths). This way SaveGame doesn't need to be modified when you add a variable to Player or Bank.

Here's the idea:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Save the state of a player.
void Player::Save (ostream & ofs) const
{ ofs   << name << delim
           << exp << delim
           << money << delim;
}
void Player::Load (ifstream & ifs)
{  ifs >> name >> exp >> money;
}

//  Ditto for Bank::Save and Bank::Load

// Save the state of the game 
void SaveGame (const Player& p, const Bank& b)
{  std::ofstream saveState("save_state.dat");
    if(saveState.fail()) 
      throw std::runtime_error("Unable to open save state file.");
    p.Save (ofs);
    b.Save (ofs);
    saveState.close();
}



Ok well i dont want to mess with any of that i guess, so i would just use the prototype method.
So should i make a class for everything? like a game class and stuff?
Topic archived. No new replies allowed.
Pages: 12