Improving my overload constructor's number of arguments

I want to create a game that runs in the command prompt. Not sure if it'll be only text based or will have basic ASCII art yet. But anyways, I'm setting up the class that will store player data.

My question is:
I have a lot of member variables in my class. Is there a better way to type my overload constructor than what I have now? Otherwise each time I add a new variable, it's going to make a very very long list of arguments.

1
2
3
4
        // Overload constructor
        Player(const std::string& userID, const std::string& user, const int userHealth, const int userExp,
               const double userBal, const double userBankBal, std::vector<std::string>& userInv,
               std::vector<std::string>& userBankItems);


So far my Player.h file includes:
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
38
39
40
41
42
43
#include <iostream>
#include <string>
#include <vector>

#ifndef PLAYER_H
#define PLAYER_H

class Player {
    // member variables:
    private:
        std::string UUID;
        std::string username;
        int health;
        int experience;
        double balance;
        double bankBalance;
        std::vector<std::string> inventory;
        std::vector<std::string> bankItems;


    // constructors, destructor, and member functions:
    public:
        // Default constructor
        Player();

        // Overload constructor
        Player(const std::string& userID, const std::string& user, const int userHealth, const int userExp,
               const double userBal, const double userBankBal, std::vector<std::string>& userInv,
               std::vector<std::string>& userBankItems);

        // Destructor
        Player::~Player();

        // Accessor Functions
        std::string getUserID() const;
        std::string getUser() const;
        int getUserHealth() const;
        int getUserExp() const;
        double getUserBal() const;
        double getUserBankBal() const;

};
#endif 


Help would be appreciated, thanks!

Edit: Also, any tips are welcome as well. Just please keep in mind that I am still a beginner in C++.
Last edited on
You could give default initialisers for members which could often be defaulted.
And then overload the constructors. For example:

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
class Player {

    private:

        std::string UUID;
        std::string username;

        int health = 20 ;
        int experience = 0 ;
        double balance = 100 ;
        double bankBalance = 0 ;
        std::vector<std::string> inventory ; // default initialised to an empty vector
        std::vector<std::string> bankItems ; // default initialised to an empty vector

    public:

        Player( std::string id, std::string name ) // two arguments
            : UUID( std::move(id) ), username( std::move(name) )
        { /* validate id, name. etc. */ }

        Player( std::string id, std::string name, int health, int experience ) // four arguments
            : UUID( std::move(id) ), username( std::move(name) ), health(health), experience(experience)
        { /* validate id, name, health, experience. etc. */ }

        // etc.
};
JLBorges wrote:
You could give default initialisers for members which could often be defaulted.
And then overload the constructors. For example:
...

Thanks for your reply!

What's this part of the code do..?
UUID( std::move(id) ), username( std::move(name) )

: UUID( std::move(id) ), username( std::move(name) ), health(health), experience(experience)

Also, what do you mean "validate id name. etc." Sorry for my lack of knowledge.

Thanks!
> What's this part of the code do..?

It initialises the two members UUID and username

: UUID( std::move(id) ), username( std::move(name) ) is the member initializer list
https://en.cppreference.com/w/cpp/language/initializer_list

If you are unfamiliar with move semantics, ignore the std::move for now; write it as
1
2
Player( std::string id, std::string name ) : UUID(id), username(name))
{ /* validate id, name. etc. */ }


> what do you mean "validate id name. etc."

The class may have (often would have) invariants: for example, that the name or id can't be empty strings.
It is the responsibility of the constructor to establish the class invariant;
do something to ensure that the object is not initialised to an invalid state.
For example:
1
2
3
4
5
6
7
Player( std::string id, std::string name ) : UUID(id), username(name)
{ 
    if( name.empty() ) name = "unknown" ; // silently correct the name 
                                          // (the alternative would be to throw an exception)

    // etc.    
}
Topic archived. No new replies allowed.