Way to better what I have done

Hi all

Quick run down, I am self taught at C++, I have been doing it for about 2-3months. I have done the SoloLearn tutorial and I am very keen to get better at what I have done. I have also got some books, and am trying to get better.

I am looking for somewhere where I can ask questions when I cannot find them elsewhere, and I hope this is the place!

So I will start off, I made this simple code to practice what I have learnt.

Any recommendations on how to improve, or what I should look at / focus on so as to get better? Any areas in particular?

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
#include <iostream>
#include <string>
using namespace std;

class defaultClass
{
public:
    defaultClass()
    {
        cout << "constructor\n";
    }

    ~defaultClass()
    {
        cout << "destructor\n";
    }

    void setSpeed (int as)
    {Speed = as;}

    void setPower (int ap)
    {Power = ap;}

    void setHealth (int hp)
    {health = hp;}

    void setRange (int rn)
    {range = rn;}

     void setHealing (int hl)
    {healing = hl;}

    void setcharacterName (string cn)
    { characterName = cn;}

protected:
    int Speed;
    int Power;
    int health;
    int range;
    int healing;
    string characterName;
};

class healerClass : public defaultClass
{
public:
    healerClass()
    {cout << "Healer class constructor\n";}

    ~healerClass()
    {cout << "Healer class destructor\n";}

    void attack()
    {cout << "Healer stats: Speed: " << Speed << " Power: " << Power << " Health: " << health << " Range: " << range << " Healing: " << healing << endl;}
};

class fighterClass : public defaultClass
{
public:
    fighterClass()
    {cout << "Fighter class constructor\n";}

    ~fighterClass()
    {cout << "Fighter class destructor\n";}

    void attack()
    {cout << "Fighter stats: Speed: " << Speed << " Power: " << Power << " Health: " << health << " Range: " << range << " Healing: " << healing << endl;}
};

class archerClass : public defaultClass
{
public:
    archerClass()
    {cout << "Archer class constructor\n";}

    ~archerClass()
    {cout << "Archer class destructor\n";}

    void attack()
    {cout << "Archer stats: Speed: " << Speed << " Power: " << Power << " Health: " << health << " Range: " << range << " Healing: " << healing << endl;}
};

class cavalryClass : public defaultClass
{
public:
    cavalryClass()
    {cout << "Cavalry class constructor\n";}

    ~cavalryClass()
    {cout << "Cavalry class destructor\n";}

    void attack()
    {cout << "Cavalry stats: Speed: " << Speed << " Power: " << Power << " Health: " << health << " Range: " << range << " Healing: " << healing << endl;}
};

class civilianClass : public defaultClass
{
public:
    civilianClass()
    {cout << "Civilian class constructor\n";}

    ~civilianClass()
    {cout << "Civilian class destructor\n";}

    void attack()
    {cout << "Civilian stats: Speed: " << Speed << " Power: " << Power << " Health: " << health << " Range: " << range << " Healing: " << healing << endl;}
};

int main()
{
    defaultClass  dc1;
    healerClass   hc1;
    fighterClass  fc1;
    archerClass   ac1;
    cavalryClass  cc1;
    civilianClass cv1;

    defaultClass *t1 = &hc1;
    defaultClass *t2 = &fc1;
    defaultClass *t3 = &ac1;
    defaultClass *t4 = &cc1;
    defaultClass *t5 = &cv1;


    t1->setSpeed(5);
    t1->setPower(5);
    t1->setHealth(300);
    t1->setRange(10);
    t1->setHealing(25);
    t1->setcharacterName("Healer");

    t2->setSpeed(80);
    t2->setPower(90);
    t2->setHealth(700);
    t2->setRange(1);
    t2->setHealing(0);
    t2->setcharacterName("Fighter");

    t3->setSpeed(100);
    t3->setPower(75);
    t3->setHealth(450);
    t3->setRange(8);
    t3->setHealing(0);
    t3->setcharacterName("Archer");

    t4->setSpeed(70);
    t4->setPower(100);
    t4->setHealth(1000);
    t4->setRange(1);
    t4->setHealing(0);
    t4->setcharacterName("Cavalry");

    t5->setSpeed(50);
    t5->setPower(10);
    t5->setHealth(100);
    t5->setRange(1);
    t5->setHealing(0);
    t5->setcharacterName("Civilian");

    hc1.attack();
    fc1.attack();
    ac1.attack();
    cc1.attack();
    cv1.attack();
}
Last edited on
1. It's not clear why you refer to your objects thru pointers (t1-> is the same as hc1. for example).
2. In general, you should use meaningful names for things.
3. There's a little more work to do if you're going to do object oriented programming in C++. You need to think ahead a bit (object oriented design) and then you implement that.
1 - I was just following what I have learnt in tutorials. Is there an advantage of any sorts using pointers in this situation?

2 - I have tried to use meaningful names,the exception being the pointers. Is there any others that you dont think are meaningful. the defaultClass is called DC after Defauly Class etc.

3 - anything particular that makes you say as such? What can I / should I focus on to improve?

Finally, I appreciate your opinion and the time you have taken to help

Tej
1. No, but you're missing an important point. C++ supports procedural and object oriented programming. And typically, C++ programs use a mix of both techniques. It helps to be clear what code is using what paradigm.

Procedural programming uses classes as abstract data types to control resource management and templates to do generic things.

Object oriented programming uses classes as objects and interfaces. And they use virtual functions for methods and possibly RTTI. The object oriented facility in C++ only works thru pointers (or references).

Example:
Let's say we have your Fighter, Archer, Cavalry and Civilian objects, all derived from Person. Typically, you'll need to hold them in a collection, like:
 
typedef std::vector<Person*> characters_type


Then, in the game loop, you'll probably want to run the attack() method on each. The OO mechanism makes the call to the right attack() method.
1
2
3
4
5
6
7
8
9
10
11
void run(characters_type& characters) {
    for (bool quit = false; !quit; ) {
        // do other stuff ...

        for (Person* character : characters) {
            character->attack();
        }

        // do other stuff ...
    }
}


And to create your characters, you use a factory of some kind. This code reads a json string like:
 
{ "name1" : "archer", "name2" : "archer", "name3" : "civilian" }


The factory that reads it using RapidJSON might look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
characters_type create_characters(const std::string& json_config) {
    characters_type characters;

    rapidjson::Document doc;
    doc.Parse(json_config.c_str());
    for (auto p = doc.MemberBegin(); p != doc.MemberEnd(); ++p) {
        if (p->value.IsString() && !strcmp(p->GetString(), "archer")) {
            characters.push_back(new Archer(p->name.GetString());
        }
        if (p->value.IsString() && !strcmp(p->GetString(), "civilian")) {
            characters.push_back(new Civilian(p->name.GetString());
        }
        // and so on ...
    }

    return characters;
}


2. Your names are ok. Personally, I'm not hung up on style. Just pick any style and be consistent through the program.

3. Not sure what else to say other than, please come back with any questions.
Last edited on
sorry for the delay, ive been away on holiday.

I think I understand the difference between procedural, and OO programming. I presume what I have done is procedural, in that I am referring to my classes to keep data size down, ad it is only used as a template. But I continually refer to that exact class to get what I want

Whereas in OO i would need the class, but it would be indirectly referenced? In this example you wrote:

1
2
3
4
5
6
7
8
9
10
11
void run(characters_type& characters) {
    for (bool quit = false; !quit; ) {
        // do other stuff ...

        for (Person* character : characters) {
            character->attack();
        }

        // do other stuff ...
    }
}


I would then be calling an attack by having the correct character chosen as the parameter, and then //do other stuff
followed by the 'Person' pointing to the right character to make them do the attack?

regarding the naming, you have gone over my head as I have never used JSON. what is that doing? Might it be better to come back to that at some other point, or is that an important point to learn? i did look up google, but all i could see was links to github

are there any example works you think I could do to better my OO skills?

thank you
thank you also
defaultClass is not a good name. It doesn't say anything for what an object of this class is good for. Maybe you name it CharacterClass. Then the characterName member could be just Name.

Put things like this:
1
2
3
4
5
6
    t1->setSpeed(5);
    t1->setPower(5);
    t1->setHealth(300);
    t1->setRange(10);
    t1->setHealing(25);
    t1->setcharacterName("Healer");
Inside the constructor:
1
2
3
4
5
6
7
8
9
healerClass()
{
    setPower(5); // or Power = 5;
    setHealth(300);
    setRange(10);
    setHealing(25);
    setcharacterName("Healer");
    cout << "Healer class constructor\n";
}
This way you could use multiple instances of healerClass without repeating the basic settings.
Topic archived. No new replies allowed.