I made this code that has 4 classes. The SpecialCharacter
class has 2 bases, Hero
and Enemy
, both of which have Person
as their base class.
#include <iostream>
class Person {
private:
char* name;
int level;
public:
Person() {
name = nullptr;
level = 0;
}
Person(char* name, int level) {
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
this->level = level;
}
Person(const Person& p) {
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
level = p.level;
}
virtual ~Person() {
delete[] name;
}
Person& operator=(const Person& p) {
if (this != &p) {
delete[] name;
name = new char[strlen(p.name) + 1];
strcpy(name, p.name);
level = p.level;
}
return *this;
}
bool operator<(const Person& p) const {
return strcmp(this->name, p.name) < 0;
}
friend std::istream& operator>>(std::istream& is, Person& p) {
char nameTemp[100];
is >> nameTemp >> p.level;
delete[] p.name;
p.name = new char[strlen(nameTemp) + 1];
strcpy(p.name, nameTemp);
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Person& p) {
os << "name " << p.name << "\n";
os << "level " << p.level << "\n";
return os;
}
};
class Hero : virtual public Person {
private:
char* ability;
public:
Hero() : Person() {
ability = nullptr;
}
Hero(char* name, int level, char* ability) : Person(name, level) {
this->ability = new char[strlen(ability) + 1];
strcpy(this->ability, ability);
}
Hero(const Hero& h) : Person(h) {
this->ability = new char[strlen(h.ability) + 1];
strcpy(this->ability, h.ability);
}
virtual ~Hero() {
delete[] ability;
}
Hero& operator=(const Hero& h) {
if (this != &h) {
Person::operator=(h);
delete[] ability;
this->ability = new char[strlen(h.ability) + 1];
strcpy(this->ability, h.ability);
}
return *this;
}
friend std::istream& operator>>(std::istream& is, Hero& h) {
is >> static_cast<Person&>(h);
char tempAbil[100];
is >> tempAbil;
delete[] h.ability;
h.ability = new char[strlen(tempAbil) + 1];
strcpy(h.ability, tempAbil);
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Hero& h) {
os << static_cast<const Person&>(h);
os << "ability " << h.ability << "\n";
return os;
}
};
class Enemy : virtual public Person {
protected:
char* type;
public:
Enemy() : Person() {
type = nullptr;
}
Enemy(char* name, int level, char* type) : Person(name, level) {
this->type = new char[strlen(type) + 1];
strcpy(this->type, type);
}
Enemy(const Enemy& e) : Person(e) {
this->type = new char[strlen(e.type) + 1];
strcpy(this->type, e.type);
}
Enemy& operator=(const Enemy& e) {
if (this != &e) {
Person::operator=(e);
delete[] type;
type = new char[strlen(e.type) + 1];
strcpy(type, e.type);
}
return *this;
}
virtual ~Enemy() {
delete[] type;
}
friend std::istream& operator>>(std::istream& is, Enemy& e) {
is >> static_cast<Person&>(e);
char temptype[100];
is >> temptype;
e.type = new char[strlen(temptype) + 1];
strcpy(e.type, temptype);
return is;
}
friend std::ostream& operator<<(std::ostream& os, const Enemy& e) {
os << static_cast<const Person&>(e);
os << "type " << e.type << "\n";
return os;
}
};
class SpecialCharacter : public Hero, public Enemy {
private:
int team;
public:
SpecialCharacter() : Person(), Hero(), Enemy() {
team = 0;
}
SpecialCharacter(char* name, int level, char* ability, char* type, int team) : Person(name, level), Hero(name, level, ability), Enemy(name, level, type) {
this->team = team;
}
SpecialCharacter(const SpecialCharacter& sp) : Person(sp), Hero(sp), Enemy(sp) {
this->team = sp.team;
}
SpecialCharacter& operator=(const SpecialCharacter& sp) {
if (this != &sp) {
Hero::operator=(sp);
this->type = sp.type;
this->team = sp.team;
}
return *this;
}
friend std::istream& operator>>(std::istream& is, SpecialCharacter& sp) {
is >> static_cast<Hero&>(sp);
char temptype[100];
is >> temptype;
sp.type = new char[strlen(temptype) + 1];
strcpy(sp.type, temptype);
is >> sp.team;
return is;
}
friend std::ostream& operator<<(std::ostream& os, const SpecialCharacter& sp) {
os << static_cast<const Hero&>(sp);
os << "type " << sp.type << "\n";
os << "team number " << sp.team << "\n";
return os;
}
};
int main()
{
Person** pers = new Person * [5];
int i = 0, r;
while (i < 5) {
r = rand() % 3;
if (r == 0) {
std::cout << "Enter info for hero\n";
Hero* e = new Hero();
std::cin >> *e;
pers[i] = e;
}
else if (r == 1) {
std::cout << "Enter info for enemy\n";
Enemy* in = new Enemy();
std::cin >> *in;
pers[i] = in;
}
else {
std::cout << "Enter info for special character\n";
SpecialCharacter* ps = new SpecialCharacter();
std::cin >> *ps;
pers[i] = ps;
}
i++;
}
for (int j = 0; j < 5; j++) {
Hero* e = dynamic_cast<Hero*>(pers[j]);
if (e != nullptr) {
std::cout << *e;
continue;
}
Enemy* in = dynamic_cast<Enemy*>(pers[j]);
if (in != nullptr) {
std::cout << *in;
continue;
}
SpecialCharacter* ps = dynamic_cast<SpecialCharacter*>(pers[j]);
if (ps != nullptr) {
std::cout << *ps;
continue;
}
}
}
I tried to overload the <<
and >>
operators for SpecialCharacter
by using static_cast
, which makes it so that it first reads/prints out the objects as a Hero
type, after which it reads/prints out the member values of the Enemy
and the SpecialCharacter
.
However, when I tested this code out in main()
, it only displays the name
, level
and abilities
for the SpecialCharacter
objects, AKA the members from the Person
and Hero
classes.
Can anyone help me understand why this is happening? Is it because of how I used dynamic_cast
in the for
loop from main()
? Or have I overloaded the operators for SpecialCharacter
incorrectly?
SpecialCharacter
derives from Hero
. In your printing loop, your 1st dynamic_cast
check for Hero*
will succeed for SpecialCharacter
objects, and then you continue
to the next iteration, so you never get a chance to print out those objects' type
and team
members.
Your printing loop should be checking for SpecialCharacter*
first instead of last.
for (int j = 0; j < 5; j++) {
// DO THIS HERE!
SpecialCharacter* ps = dynamic_cast<SpecialCharacter*>(pers[j]);
if (ps != nullptr) {
std::cout << *ps;
continue;
}
Hero* e = dynamic_cast<Hero*>(pers[j]);
if (e != nullptr) {
std::cout << *e;
continue;
}
Enemy* in = dynamic_cast<Enemy*>(pers[j]);
if (in != nullptr) {
std::cout << *in;
continue;
}
/* NOT HERE !
SpecialCharacter* ps = dynamic_cast<SpecialCharacter*>(pers[j]);
if (ps != nullptr) {
std::cout << *ps;
continue;
}
*/
}