Creating different weapons in class

Pages: 1234
So i'm making a game where you fight dinosaurs in an arena, there will be different weapons. Instead of creating each weapon individually, I want to create one weaponName variable and one weaponAttackPower variable and use those as a base for creating the guns. I'll do the same for the dinosaurs and items. How would I go about doing this? What is the best approach.

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <fstream>

class Player
{
    public:
        Player() = default;
        ~Player() = default;

        void DamagePlayer(float damageDealt);

        void SavePlayerData();

    private:
        std::string playerName = "Default_Player";
        float playerHealth = 100;
        std::string weaponName = "Default_Weapon";
        float weaponAttackPower = 0;

        void RestorePlayerData();
};

void Player::SavePlayerData()
{
    std::ofstream Save("PlayerData.txt");

}

class Dinosaur
{
    public:
        Dinosaur() = default;
        ~Dinosaur() = default;

        void SaveDinosaurData();

    private:
        float dinosaurHealth = 100;
        float dinosaurAttackPower = 0;
        std::string dinosaurAttackName = "Default";
        std::string dinosaurName = "Default_Dinosaur";

        void RestoreDinosaurData();
};


void Fight();
void ReturningPlayer();
void NewPlayer();

int main()
{
    std::cout << "Welcome, are you a new player or are you a returning one?" << std::endl;
    std::cout << "1) I'm New" << std::endl;
    std::cout << "2) I'm returning" << std::endl;

    int choice = 0;

    std::cin >> choice;

    switch(choice)
    {
        case 1:
            NewPlayer();
            break;
        case 2:
            ReturningPlayer();
            break;
        default:
            std::cout << "Incorrect Choice!" << std::endl;
    }

    return 0;
}

void ReturningPlayer()
{

}

void NewPlayer()
{

}

void Fight()
{

}
Last edited on
I don't understand the question:
Instead of creating each weapon individually, I want to create one weaponName variable and one weaponAttackPower variable and use those as a base for creating the guns.

Can you give a pseudocode example?
so from weaponName I can create lets say 4 different weapons:

Handgun
Shotgun
Rifle
Rocket Launcher

and from that I can assign them an attack power. So basically i'm "creating" 4 weapons with the weaponName variable instead of just outright writing:

gunHandgun
gunRifle

etc. hopefully that helps.
Last edited on
Maybe something like this:

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
#include <iostream>
#include <fstream>
#include <string>
#include <map>

class Weapon {
    int a, b;
public:
    Weapon() : a(0), b(0) {}
    Weapon(int a, int b) : a(a), b(b) {}
    int getA() { return a; }
    int getB() { return b; }
    friend std::ostream& operator<<(std::ostream& os, const Weapon& w) {
        return os << w.a << ", " << w.b;
    }
};


int main() {
    std::map<std::string, Weapon> weapon {
        {"Handgun", {1, 2}},
        {"Shotgun", {3, 4}}
    };

    std::cout << weapon["Shotgun"] << '\n';

    int a = weapon["Handgun"].getA();
    std::cout << a << '\n';
}

Last edited on
hmm, could something liek this be done?

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <string>
#include <fstream>
#include <map>

class Player
{
    public:
        Player() = default;
        ~Player() = default;

        float ModifyPlayerHealth(float modifyHealth);

        void SavePlayerData();


    private:
        std::string playerName = "Default_Player";
        float playerHealth = 100;

        void RestorePlayerData();
};

void Player::SavePlayerData()
{
    std::ofstream Save("PlayerData.txt");

}

float Player::ModifyPlayerHealth(float modifyPlayerHealth)
{
    return playerHealth - modifyPlayerHealth;
}

class Weapon
{
    public:
        float Fire();

        void SaveWeaponData();

    private:
        std::string weaponName = "Default_Weapon";
        float weaponAttackPower = 0;

        void RestoreWeaponData();
};

class Handgun : public Weapon
{
    public:
        float Fire(){return -30;};
};

class Dinosaur
{
    public:
        Dinosaur() = default;
        ~Dinosaur() = default;

        void SaveDinosaurData();

    private:
        float dinosaurHealth = 100;
        float dinosaurAttackPower = 0;
        std::string dinosaurAttackName = "Default";
        std::string dinosaurName = "Default_Dinosaur";

        void RestoreDinosaurData();
};


void Fight();
void ReturningPlayer();
void NewPlayer();

int main()
{
    Fight();

    std::cout << "Welcome, are you a new player or are you a returning one?\n" << std::endl;

    std::cout << "1) I'm New" << std::endl;
    std::cout << "2) I'm returning" << std::endl;

    int choice = 0;

    std::cin >> choice;

    switch(choice)
    {
        case 1:
            NewPlayer();
            break;
        case 2:
            ReturningPlayer();
            break;
        default:
            std::cout << "Incorrect Choice!" << std::endl;
    }

    return 0;
}


void ReturningPlayer()
{

}


void NewPlayer()
{

}


void Fight()
{
    Player plr;
    Handgun handgun;

    std::cout << plr.ModifyPlayerHealth(-handgun.Fire());
}
Last edited on
Shouldn't Player and Dinosaur have a common base class since they share common fields and methods ?
Obviously I've totally misunderstood what you are trying to do. I thought that was exactly what you were trying to avoid. Maybe someone else can help.
Well, i'm not really sure what i'm doing. I would just like to know what the best and most simple approach to creating weapons, items and other things is easily. I just suggested the way above because it's something I learned a long time ago, but I could be wrong in assuming its a good way to do things. I need to contain things to their own classes and have each class manage itself. As for having the player and dinosaur classes have a common base, it's possible. I'm not done writing the code for either, the player will have a lot more stuff that dinosaurs dont but I could have an entity or Actor class that they inherit from.

Something like this:

1
2
3
4
5
6
7
8
9
10
class Entity
{
    public:
        Entity() = default;
        ~Entity() = default;
    
    private:
        std::string entityName = "DefaultEntity";
        float entityHealth = 1;
};


Thats just basic, didnt add a lot of stuff to it but the other classes could inherit from this.
Last edited on
ok, so here is my solution, I just did polymorphism with inheritance, that way I can create different weapons, dinosaurs and later on, items by just inheriting. I might be doing something wrong or not quite right though so I'm posting my code for review:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <iostream>
#include <string>
#include <fstream>
#include <map>

class Player
{
    public:
        Player() = default;
        ~Player() = default;

        void SavePlayerData();


    private:
        std::string playerName = "Default_Player";
        float playerHealth = 100;

        void RestorePlayerData();
};

void Player::SavePlayerData()
{
    std::ofstream Save("PlayerData.txt");


}

class Weapon
{
    public:
        Weapon() = default;
        virtual ~Weapon() = default;

        virtual void SetWeaponName(std::string weapName){ weaponName = weapName; }
        std::string ReturnWeaponName() const { return weaponName; }

        virtual void SetWeaponDamage(float weapDamage){ weaponDamage = weapDamage; }
        float ReturnWeaponDamage() const { return weaponDamage; }

    private:
        std::string weaponName = "Default_Weapon";
        float weaponDamage = 0;
};

class Handgun : public Weapon
{

};


class Dinosaur
{
    public:
        Dinosaur() = default;
        virtual ~Dinosaur() = default;

        void SaveDinosaurData();

        virtual void SetDinosaurName(std::string name){ dinosaurName = name; };
        std::string ReturnDinosaurName() const { return dinosaurName; };

        virtual void SetDinosaurAttackPower(){};
        float ReturnDinosaurAttackPower() const;

        virtual void SetDinosaurAttackName(){};
        std::string ReturnDinosaurAttackName() const;

        virtual void SetDinosaurHealth(){};
        float ReturnDinosaurHealth() const;

    private:
        float dinosaurHealth = 100;
        float dinosaurAttackPower = 0;
        std::string dinosaurAttackName = "Default";
        std::string dinosaurName = "Default_Dinosaur";

        void RestoreDinosaurData();
};


class Utahraptor : public Dinosaur
{

};

class Allosaurus : public Dinosaur
{

};


void Fight();
void ReturningPlayer();
void NewPlayer();

int main()
{
    //int choice = 0;

    Dinosaur *dino = new Allosaurus;
    dino->SetDinosaurName("Allosaurus");

    Weapon *weap = new Handgun;
    weap->SetWeaponName("Handgun");
    weap->SetWeaponDamage(30.00);

    std::cout << dino->ReturnDinosaurName() << std::endl;
    std::cout << weap->ReturnWeaponName() << std::endl;

    delete dino;
    delete weap;


/*
    while(choice != -1)
    {
        std::cout << "Welcome, are you a new player or are you a returning one?\n" << std::endl;

        std::cout << "1) I'm New" << std::endl;
        std::cout << "2) I'm Returning" << std::endl;
        std::cin >> choice;

        switch(choice)
        {
            case 1:
                NewPlayer();
                break;
            case 2:
                ReturningPlayer();
                break;
            default:
                std::cout << "Incorrect Choice!" << std::endl;
        }
    }
*/
    return 0;
}


void ReturningPlayer()
{

}


void NewPlayer()
{

}


void Fight()
{

}
Last edited on
How do the Weapons and Dinosaurs differ? Do they have different fields and methods.
I think you're having trouble with the difference between and class and an instance of the class. You can probably have a single Player class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Player
{
    public:
        Player() = default;
        ~Player() = default;

        void takeDamage(float damageDealt);
        void save();

    private:
        std::string name = "Default_Player";
        float health = 100;
        Weapon weapon;
        void restore();
};

Notice that I removed "Player" from the names of the members. It's redundant to name player members with "player".

Now you have two instances of class Player, a human and a dinosaur:
Player human, dinosaur;

You'll also need a single Weapon class. Something like:
1
2
3
4
5
6
7
8
9
10
11
class Weapon {
    Weapon(unsigned _damage, unsigned _capacity, unsigned firingRate) :
        damage(_damage),  capacity(_capacity), size(_capacity), firingRate(_firingRate)
        {}
       // getter methods
private:
    unsigned damage;  // damage dealt when fired once.
    unsigned capacity;  // can't hold more than this many rounds
    unsigned size;        // current number of rounds.
    double firingRate;  // max number of rounds per minute.
};


And you can define several sorts of weapons like:
1
2
3
Weapon revolver(10, 6, 120);            // six shooter
Weapon tommyGun(10, 200, 400);    // Shoots lots of bullets fast.
Weapon fiftyCal(30, 40, 6);      // Big magazine & damage, but shoots slowly. 


So could I just create an Entity class and create everything from that? Everything is an Entity, or Actor, whichever you want to call it, speaking in game design terms. I could then just either create child classes named Player, Weapon, Dinosaur etc or create objects for them.
Well it depends. Lets say you have a class Actor who store a name and the health. If Player and dinosaur don't have different fields the there is no pint for inheritance, you just create a player and dinosaur var of type Actor.

On the other hand if Actor has an method fight which works different in Player and Dinosaur then you need to inherit from Actor and implement the function in Player and Dinosaur differently. Same for Weapon class.
ok so if I have the entity class then for weapons I have FireWeapon(), I would then just create a class named weapon that inherits Entity and define the methods in there?

So far I just have this:

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <string>
#include <fstream>
#include <map>

class Entity
{
    public:
        Entity() = default;
        ~Entity() = default;

    private:
        std::string entityName = "Default_Entity";
        int entityHealth = 0;
        int entityDamageDealt = 0;
};

void Fight();
void ReturningPlayer();
void NewPlayer();

int main()
{
    int choice = 0;

    Entity Player, Dinosaur, Weapon;

/*
    while(choice != -1)
    {
        std::cout << "Welcome, are you a new player or are you a returning one?\n" << std::endl;

        std::cout << "1) I'm New" << std::endl;
        std::cout << "2) I'm Returning" << std::endl;
        std::cin >> choice;

        switch(choice)
        {
            case 1:
                NewPlayer();
                break;
            case 2:
                ReturningPlayer();
                break;
            default:
                std::cout << "Incorrect Choice!" << std::endl;
        }
    }
*/
    return 0;
}


void ReturningPlayer()
{

}


void NewPlayer()
{

}


void Fight()
{

}


For this simple game this should be enough, all of these things will use the variables in Entity, but weapons will have methods like Fire(), Reload() etc, so should a child class be created for those methods?
I'm not sure you want a single entity base class. As you've defined it, what is the "health" of a weapon? What is the "damage dealt" of a dinosaur?
You want a map of all possible weapons somewhere, as in tpb's answer in the fourth post.

In a sense, Dinosaurs could also have their own "DinoWeapons" , idk, Claw, ViciousClaw, Bite, with their own damage, accuracy, and fire rates. That could be a different map.
Sample mini simulator
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <chrono>
#include <thread>
#include <random>

using namespace std::chrono_literals;

class Weapon
{
public:
    Weapon() : 
        name_("Unknown"), 
        verb_("Unknown"), 
        damage_(0),
        accuracy_(0),
        fire_rate_(0)
    {        
    }

    // damage - 1+
    // accuracy - 0 to 100 (higher is better)
    // fire_rate - 0 to 100 (lower is faster)
    Weapon(std::string name, std::string verb, unsigned damage, unsigned accuracy, unsigned fire_rate) :
        name_(name),
        verb_(verb),
        damage_(damage),
        accuracy_(accuracy),
        fire_rate_(fire_rate)
    {
    }
    Weapon(const Weapon& other)
    {
        name_ = other.name_;
        verb_ = other.verb_;
        damage_ = other.damage_;
        accuracy_ = other.accuracy_;
        fire_rate_ = other.fire_rate_;
    }

    bool operator< (const Weapon& other) const
    {
        return name_ < other.name_;
    }
    
    std::string Name() const { return name_; }
    std::string Verb() const { return verb_; }
    unsigned Damage() const { return damage_; }
    unsigned Accuracy() const { return accuracy_; }
    unsigned FireRate() const { return fire_rate_; }

private:
    std::string name_;
    std::string verb_;
    unsigned damage_;
    unsigned accuracy_;
    unsigned fire_rate_;
};

enum WeaponName
{
    KNIFE,
    REVOLVER,
    BERETTA_M9
};

enum DinoWeaponName
{
    CLAW,
    BITE,
    VICIOUS_CLAW
};


std::map<WeaponName, Weapon> Weapons
{
    { KNIFE, {"Knife", "slashes", 2, 70, 40} },
    { REVOLVER, {"Revolver", "shoots", 4, 50, 50} },
    { BERETTA_M9, {"Beretta M9", "shoots", 10, 80, 20} },
};

std::map<DinoWeaponName, Weapon> DinoWeapons
{
    { CLAW, {"Claw", "claws", 1, 50, 40} },
    { BITE, {"Bite", "lunges", 2, 75, 50} },
    { VICIOUS_CLAW, {"Vicious Claw", "viciously slashes", 8, 95, 60} },
};

class Dinosaur
{
public:
    Dinosaur(std::string name, Weapon dino_weapon, int health) :
        name_(name),
        dino_weapon_(dino_weapon),
        health_(health)
    {
    }

    void TakeDamage(int damage) { health_ -= damage; }

    std::string Name() const { return name_; }
    Weapon GetWeapon() const { return dino_weapon_; }
    int Health() const { return health_; }

private:
    std::string name_;
    Weapon dino_weapon_;
    int health_;
};

class Human
{
public:
    Human(std::string name, Weapon weapon, int health) :
        name_(name),
        weapon_(weapon),
        health_(health)
    {
        AddWeapon(weapon);
    }
    void AddWeapon(Weapon weapon)
    {
        weapons_.insert(weapon);
    }

    void Equip(const Weapon& weapon)
    {
        if (weapons_.find(weapon) == weapons_.end())
        {
            std::cout << "You do not own the weapon "<< weapon.Name() << '\n';
            return;
        }
        weapon_ = weapon;
    }

    void TakeDamage(int damage) { health_ -= damage; }

    void Fight(Dinosaur& dino)
    {
        if (dino.Health() <= 0)
        {
            std::cout << dino.Name() << " is already dead.\n";
            return;
        }
        if (health_ <= 0)
        {
            std::cout << name_ << " is dead and cannot start a Fight.\n";
            return;
        }

        std::cout << name_ << " (" << health_ << " HP), " << weapon_.Name() << 
                    ", prepares to fight\n" << 
                     dino.Name() << " (" << dino.Health() << " HP), " << dino.GetWeapon().Name() << " !\n\n";

        std::cout << "3..." << std::flush;
        std::this_thread::sleep_for(1s);
        std::cout << "2..." << std::flush;
        std::this_thread::sleep_for(1s);
        std::cout << "1..." << std::flush;
        std::this_thread::sleep_for(1s);
        std::cout << "FIGHT!\n\n" << std::flush;
        std::this_thread::sleep_for(1s);


        const Weapon& dino_weapon = dino.GetWeapon();
        long total_time = 0;
        int tick = 5;  // Some divisor of all possible fire rates

        while (true)
        {
            // Human tries to hit dino if Accuracy RNG favors him
            if (total_time % weapon_.FireRate() == 0)
            {
                if (rd_()%101 <= weapon_.Accuracy())
                {
                    std::cout << name_ << " " << weapon_.Verb() << " with the " << 
                                 weapon_.Name() << " for " << weapon_.Damage() << " damage.\n";
                    dino.TakeDamage(weapon_.Damage());
                    if (dino.Health() <= 0)
                    {
                        std::cout << name_ << " has defeated " << dino.Name() << "!!!\n";
                        break;
                    }
                }
                else
                {
                    std::cout << name_ << " misses.\n";
                }
            }

            // Dino tries to hit human
            if (total_time % dino_weapon.FireRate() == 0)
            {
                if (rd_()%101 <= dino_weapon.Accuracy())
                {
                    std::cout << dino.Name() << " " << dino_weapon.Verb() << " with the " << 
                                 dino_weapon.Name() << " for " << dino_weapon.Damage() << " damage.\n";
                    TakeDamage(dino_weapon.Damage());
                    if (health_ <= 0)
                    {
                        std::cout << dino.Name() << " has defeated " << name_ << "!!!\n";
                        break;
                    }
                }
                else
                {
                    std::cout << dino.Name() << " misses.\n";
                }
            }            

            total_time+=tick; 
        }
        std::cout << "\nRemaining health: " << health_ << "\n\n\n";
    }


private:
    std::string name_;
    Weapon weapon_; // Currently equipped weapon
    std::set<Weapon> weapons_;
    int health_;
    std::random_device rd_;
};

int main() 
{
    Human player("Chuck Norris", Weapons[KNIFE], 100);
    player.AddWeapon(Weapons[BERETTA_M9]);

    Dinosaur raptor1("Raptor", DinoWeapons[CLAW], 20);
    Dinosaur raptor2("Raptor", DinoWeapons[CLAW], 22);
    Dinosaur boss("T-Rex", DinoWeapons[VICIOUS_CLAW], 100);
    Dinosaur super_boss("Ultra T-Rex", DinoWeapons[VICIOUS_CLAW], 500);
    Dinosaur raptor3("Raptor", DinoWeapons[CLAW], 19);
    
    player.Fight(raptor1); // Knife

    player.Equip(Weapons[BERETTA_M9]);  // Finding a better weapon
    player.Fight(raptor2);
    player.Fight(boss);
    player.Fight(super_boss);
    player.Fight(raptor3);  // Player likely dead and cant fight further

    return 0;
}


https://repl.it/@icy_1/QuarterlyHarmfulMethod

small excerpt of possible output
Chuck Norris (93 HP), Beretta M9, prepares to fight
Raptor (22 HP), Claw !

3...2...1...FIGHT!

Chuck Norris shoots with the Beretta M9 for 10 damage.
Raptor misses.
Chuck Norris shoots with the Beretta M9 for 10 damage.
Chuck Norris shoots with the Beretta M9 for 10 damage.
Chuck Norris has defeated Raptor!!!

Remaining health: 93
Last edited on
Hi Chay,

I just wanted to mention the point of an Entity class, I think I gave advice about this a long time ago.

It has to do with polymorphism and inheritance. A part of that is to have common virtual functions in a base class, then override them in derived classes. The idea of an Entity base class is to allow for functions like Draw, Move or Animate that a GUI game might have, these would apply to every graphical thing on the screen including Players, Enemies and Weapons and many other things. If it is not a GUI game then you may not need this class at all. Then there is the Actor class, because both Players and Enemies might have a health value, so this member variable is "Pushed Up" to the Actor class.

One big thing to think about is the concept of behavior. One usually has different classes to implement different behaviors. One way of looking at this: if 2 objects differ only in the value of their member variables, then one probably doesn't need to have different classes for them. But also consider this scenario: if it's the type of game where one can collect things, and there are magazines which only fit certain types of weapons, then you could have separate classes for each type of weapon (like in your code above) and magazine. Then a LoadMag function could only accept the right type of Mag, an error otherwise. This is an example of using the C++ type system to advantage, in C++ types are a big thing. A counter example is having a member variable that is a string describing the type. This has problems of it's own, I wouldn't recommend it.

Btw, please don't use new even for trivial examples, especially for just obtaining a pointer. Consider learning smart pointers like std::unique_ptr.

Also remember that public inheritance means an "IS A type of" relationship.
Thank you for your responses. It will take me some time to look through and process all the code in the one post above.

The hardest thing for me is comprehending stuff, its just a disability I have unfortunately, I've always had a hard time understanding some things and truly grasping things unless its explained just right, which is why im still in the beginner section after almost 11 years of programming C++.

But I really want to understand classes, everything else I can understand, I just cant GET classes for some reason. I understand the syntax and why classes are used and what they're used for I just cant seem to get WHEN to use certain aspects of classes and things like that. When I think I've got the hang of it I post my code for help with something totally unrelated to a class sometimes and I always get asked: "Why are you doing this with your class?, why is your class like this and not liek this? why are you not doing this or that? etc", and i'm just sitting here like "I DON'T KNOW!!".

I don't get it, and it sucks because I really like programming and I want to understand it, which is why I keep coming back to it. I would liek to start writing down things about classes, all the stuff I learn, that way when I come back to it I can just read that and refresh myself. I would also like to post some simple examples of classes starting with just one class and ask how to do things with that and then work my way up.

So I would start with one class and accessing information from that, then after that, using polymorphism with one child class, then two, then move on to using virtual. I think starting from the beginning and working my way up will be best, right now im just all over the place and I think thats just confusing me even more. I'll post some code shortly and i'll see what I need help understanding.
Last edited on
Ok, so I have one class, I made this purposefully so it will just be one class that can create many objects and not need inheritance or any of that, something small:

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
44
45
46
47
48
49
50
#include <iostream>
#include <string>


class SkyrimNord
{
    public:
        SkyrimNord() = default;
        ~SkyrimNord() = default;

        void Attack();
        void Interact();
        void OpenInventory();
        void Run();
        void UseMagickSpell();

        std::string ShowName() const { return m_name; }
        std::string ShowClass() const { return m_class; }
        std::string ShowGender() const { return m_gender; }
        std::string ShowRace() const { return m_race; }

        int ShowAge() const { return m_age; }

        float ShowBaseMagicka() const { return m_baseMagicka; }
        float ShowBaseHealth() const { return m_baseHealth; }
        float ShowBaseStamina() const { return m_baseStamina; }

    private:
        std::string m_name = "Default_Nord";
        std::string m_class = "Default_Class";
        std::string m_gender = "Default_Gneder";
        const std::string m_race = "Nord";

        int m_age = 0;
        int m_inventorySlots[0];

        float m_baseMagicka = 50;
        float m_baseHealth = 100;
        float m_baseStamina = 100;
};

int main()
{
    SkyrimNord Brynjolf;
    SkyrimNord Skald;

    std::cout << Brynjolf.ShowRace() << std::endl;

    return 0;
}


Now my first problem is that when I create this class, I need access to the objects, so naturally I want to create getters and setters to access these values to set them. I defaulted them and initialized them as per the new C++ standard allwos this in classes now. I have read so much for and against getters and setters, I am unsure what to do. Obviously getters and setters are necessary for certain situations, I dont know which situations though.

I can see using getters fairly often, I mean you have the need to view stats in a game so what I have above should be ok right? as long as they're const. I could show them all at once with a simple function but I may have the need to just show one at a time or a certain one and not want to show the rest so I made them individual functions.

I dont see the point of setters though, I mean:

1
2
3
4
void SetHealth(int health)
{
    m_health = health;
}


is exactly the same thing as accessing the variable directly, your still modifying the variable just not directly which is pointless, it's like building a wall to keep people out and then putting a door in the wall. But maybe i'm missing something.

So what is my next approach here, what is the best way to create each Nord with this one class?
Last edited on
Pages: 1234