How to get field value of a child class of the parent method?

Hello. Learning c++ and have encountered a problem where I can't get the value of a variable.

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

enum MagicType {
fire,
water,
earth
air
};

MagicSpellInfo struct {
public:
 string Name;
 string Description;
 Type MagicType;
 float MinDamage;
 float MaxDamage;
 float Distance;
 float Range;

 MagicSpellInfo() :
 Name(""), Description(""), MinDamage(0.0), MaxDamage(0.0), Distance(0.0), Range(0.0), Type(fire) {}

 MagicSpellInfo(string _name, string _dsc, _mindmg float, float _maxdmg, _dst, float, float, _rng, MagicType _type) : 
 Name(_name), Description(_dsc), MinDamage(_mindmg), MaxDamage(_maxdmg), Distance(_dst), Range(_rng), Type(_type) {}
};

class IMagicSpell {
private:
 MagicSpellInfo SpellInfo;

public:
 virtual ~IMagicSpell() {}
 virtual void Use() {}

 MagicSpellInfo GetInfo() {
 return this->SpellInfo;
}

 void ShowDebugInfo() {
 cout << "Name:" << SpellInfo.Name << endl;
 cout << "Description:" << SpellInfo.Description << endl;
 cout << "Type:" << SpellInfo.Type << endl;
 cout << "Min. damage: "<< SpellInfo.MinDamage << endl;
 cout << "Max. damage: "<< SpellInfo.MaxDamage << endl;
 cout << "Distance:" << SpellInfo.Distance << endl;
 cout << "Radius:" << SpellInfo.Range << endl;
}
};

class Fireball: public IMagicSpell {
private:
 MagicSpellInfo SpellInfo;

public:
 Fireball() {
 SpellInfo.Name = "fireball";
 SpellInfo.Description = "a Powerful ball of fire that sweeps away everything in its path.";
 SpellInfo.Type = fire;
 SpellInfo.MinDamage = 30;
 SpellInfo.MaxDamage = 50;
 SpellInfo.Range = 40;
 SpellInfo.Distance = 120;
}

 virtual ~Fireball() {}

 virtual void Use() {
 cout << "Boom!" << endl;
}
};

int main() {
 setlocale(LC_ALL, "Russian");

 Fireball fireball;
fireball.ShowDebugInfo();

cin.get();
 return 0;
}


The output I get the following:
Name:
Description:
Type: 0
Min. damage: 0
Max. damage: 0
Distance: 0
Radius: 0


Although, obviously, I need to get the data specified in the constructor Fireball.
Tell me, what's wrong?
March 23rd 20 at 19:32
2 answers
March 23rd 20 at 19:34
Solution
Method IMagicSpell::ShowDebugInfo you have accesses private field IMagicSpell::SpellInfo. This field is unavailable for heirs, because it is private.
Designer-the same Fireball::Fireball, you works with private field Fireball::SpellInfo.
Field IMagicSpell::SpellInfo and Fireball::SpellInfo are different, located in different memory areas of an object Fireball and, in principle, can not overlap your data.
The size of your Fireball will be two MagicSpellInfo plus table size virtual characters.

From the reason you go to achieve the desired behavior.
The most important thing - a second instance MagicSpellInfo in the hierarchy is redundant. Fireball::SpellInfo is a duplicate, the extra field that allows you to achieve the desired functionality. Because in both of your classes you have to work with the same data field IMagicSpell::SpellInfo.
Just remove Fireball::SpellInfo.
Fireball
class Fireball: public IMagicSpell {
public:
 Fireball() {
 SpellInfo.Name = "fireball";
 SpellInfo.Description = "a Powerful ball of fire that sweeps away everything in its path.";
 SpellInfo.Type = fire;
 SpellInfo.MinDamage = 30;
 SpellInfo.MaxDamage = 50;
 SpellInfo.Range = 40;
 SpellInfo.Distance = 120;
}

 virtual ~Fireball() {}

 virtual void Use() {
 cout << "Boom!" << endl;
}
};


But now we are not compiling. The compiler will write IMagicSpell::SpellInfo is private and not available for posterity. To fix that too very easily.
There are three sections of the access fields and functions of class:
  1. private - private access only for the instance of the current class;
  2. protected - restricted access only for instances of the current class and all public heirs; access is restricted in a limited or private inheritance;
  3. public - public access, for all users of instances of the class.

We need to change access rights to IMagicSpell::SpellInfo private limited. In this case, the instances of the Fireball will be able to contact IMagicSpell::SpellInfo as their restricted field.
IMagicSpell
class IMagicSpell {
protected:
 MagicSpellInfo SpellInfo;

public:
 virtual ~IMagicSpell() {}
 virtual void Use() {}

 MagicSpellInfo GetInfo() {
 return this->SpellInfo;
}

 void ShowDebugInfo() {
 cout << "Name:" << SpellInfo.Name << endl;
 cout << "Description:" << SpellInfo.Description << endl;
 cout << "Type:" << SpellInfo.Type << endl;
 cout << "Min. damage: "<< SpellInfo.MinDamage << endl;
 cout << "Max. damage: "<< SpellInfo.MaxDamage << endl;
 cout << "Distance:" << SpellInfo.Distance << endl;
 cout << "Radius:" << SpellInfo.Range << endl;
}
};


In this form you will be able to achieve the desired functionality. But it is more important to you, it was clear how you were doing.
Thank you! Really appreciate that.) - dangelo_Senger commented on March 23rd 20 at 19:37
March 23rd 20 at 19:36
To get the value of fields of child class, the parent method cannot be - as the parent method is about the fields of the child class knows nothing;
In Your case, it is possible to declare a function ShowDebugInfo as virtual in the parent class and implement (override) this method in the child;
However, the problem may be deeper, the fact that in your child class actually contains two fields MagicSpellInfo SpellInfo - one in parent and one in child (parent class declared private and therefore inaccessible to the child); Perhaps we should declare MagicSpellInfo SpellInfo protected in the parent class and remove the duplicate from the child;
Thank you! Just the second solution and helped) - dangelo_Senger commented on March 23rd 20 at 19:39

Find more questions by tags C++