*operators returning garbage values

Write your question here.

The code makes the heroes fight against each other using the *operator.

However, when it runs, the winner is displayed in garbage values instead
of the name of the actual hero that won.

Any guess to how to solve 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
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
  Main.cpp

    #include <iostream>
    #include "Hero.h"
    
    using namespace std;
    using namespace sict;
    
    int main() {
    
    	cout << "Greek Heroes";
    	Hero moneyhunger("", 40, 4);
    	Hero hercules("Hercules", 32, 4);
    	Hero theseus("Theseus", 14, 5);
    	Hero oddyseus("Odysseus", 15, 3);
    	Hero ajax("Ajax", 17, 5);
    	Hero achilles("Achilles", 20, 6);
    	Hero hector("Hector", 30, 5);
    	Hero atalanta("Atalanta", 10, 3);
    	Hero hippolyta("Hippolyta", 10, 2);
    
    	cout << endl << "Quarter Finals" << endl;
    	const Hero& greek_winner0 = moneyhunger * hector;
    	const Hero& greek_winner1 = achilles * hector;
    	const Hero& greek_winner2 = hercules * theseus;
    	const Hero& greek_winner3 = oddyseus * ajax;
    	const Hero& greek_winner4 = atalanta * hippolyta;
    
    	cout << endl << "Semi Finals" << endl;
    	const Hero& greek_winner_semifinal1 = greek_winner1  * greek_winner2;
    	const Hero& greek_winner_semifinal2 = greek_winner3  * greek_winner4;
    
    	cout << endl << "Finals" << endl;
    	greek_winner_semifinal1 * greek_winner_semifinal2;
    	system("pause");
    	return 0;
    }


Hero.cpp

    #include "Hero.h"
    #include <iostream>
    #include <cstring>
    using namespace std;
    namespace sict {
    
    	Hero::Hero()
    	{
    		m_name[0] = '\0';
    		m_health = 0;
    		m_attack = 0;
    
    	}
    
    
    	 
    	Hero::Hero(char name[], int health, int attack)
    	{
    
    		if (m_name != nullptr || m_name != "") {
    			strcpy(m_name, name);
    
    		}
    		else {
    			m_name[0] = '\0';
    		}
    
    		m_attack = attack;
    		m_health = health;
    
    
    	}
    
    	void Hero::operator-=(int attack) {
    		if (attack > 0) {
    			m_health -= attack;
    		}
    		if (attack > m_health) {
    			m_health = 0;
    		}
    	}
    	bool Hero::isAlive() const {
    		if (m_health > 0) {
    			return true;
    		}
    		else {
    			return false;
    		}
    	}
    	int Hero::attackStrength() const {
    		if (m_attack == 0) {
    			return 0;
    		}
    		else {
    			return m_attack;
    		}
    	}
    	ostream& operator<<(ostream& os, const Hero& hero) {
    		if (hero.m_name == '\0') {
    			os << "No Hero";
    		}
    		else {
    			os << hero.m_name;
    		}
    		return os;
    	}
    	const Hero& operator*(const Hero& first, const Hero& second) {
    		cout << "Ancient Battle! ";
    		cout << first;	
    		cout << " vs ";
    		cout << second;
    		cout << " : ";
    		Hero A = first;
    		Hero B = second;
    		const Hero *winner = nullptr;
    		int max_rounds = 0;
    		while (A.isAlive() && B.isAlive() && max_rounds < 200) {
    			max_rounds++;
    			A -= B.attackStrength();
    			B -= A.attackStrength();
    		
    		}
    
    		bool draw;
    
    		if (A.isAlive() && B.isAlive()) { draw = true; }
    		else { draw = false; }
    
    		if (draw) {
    			winner = &first;
    		}
    		else if (A.isAlive())
    		{
    			winner = &first;
    		}
    		else {
    			winner = &second;
    		}
    		cout << "Winner is ";
    		cout << winner;
    		cout << " in " << max_rounds << " rounds. " << endl;
    		return *winner;
    
    	}
    }


Hero.h

    #ifndef SICT_HERO_H_
    #define SICT_HERO_H_
    #include <iostream>
    namespace sict {
    	class Hero {
    		char m_name[41];
    		int m_health;
    		int m_attack;
    	public:
    		Hero();
    		Hero(char name[], int health, int attack);
    		void operator-=(int attack);
    		bool isAlive() const;
    		int attackStrength() const;
    		friend std::ostream& operator<<(std::ostream& os, const Hero& hero);
    	};
    	const Hero& operator*(const Hero& first, const Hero& second);
    }
    #endif 
Last edited on
Line 116: winner is a pointer.

Line 141: You're outputting a pointer. Change to:
 
  cout << *winner;


BTW, why are you using C-strings and not std::string?
Last edited on
if i were to not ouput a pointer, it would give me an error saying no suitable constructor exists to convert from const sict::hero to sict::hero
Don't you want to check if name is empty instead of m_name? By the way, you can't compare C-strings using == or != because it would just compare pointers.

Instead of m_name != "" you could write name != '\0', or possibly strlen(name) != 0 but that would probably be slower.
Last edited on
I got no such error when I compiled your code. Your overload of the << operator is correct as Hero is passed as a const reference.

I did get a warning that strcpy is possibly unsafe and should not be used. Again, a reason to use std:;string rather than C-strings.
I fixed it and now it shows up names. However, it shows the different number of rounds. If it should say in 4 rounds, it displays as 3 rounds and if it should be 7 rounds, it says 6 rounds. Any guess to why?
How do you know the number of rounds it displays is off by one?

Every loop iteration, your max_rounds variable, staring at 0, increases by 1. If the loop iterates once, you get max_rounds == 1. Seems right to me.
1
2
3
4
while (A.isAlive() && B.isAlive() && max_rounds < 200) {
    			max_rounds++;
    			// ...
}
Last edited on
Topic archived. No new replies allowed.