разыменование указателя на дочерний объект

Структура Effect унаследавана от структуры EffectsStruct::bleeding

struct EffectsStruct{
            struct bleeding {
                int duration=0;
                int dmg=0;
            }bleedingObj;

            struct poisoning {
                int duration=0;
                int dmg=0;
            }poisoningObj;

            struct stunning {
                int duration=0;
                int dmg=0;
            }stunningObj;
};


struct Effect :public EffectsStruct::bleeding, public EffectsStruct::poisoning, public EffectsStruct::stunning {
   std::string type;
};

Я преобразую bleeding* в Effect*, но когда я пытаюсь разыменовать полученный Effect* программа вылетатет без ошибок

Skills::SkillStruct::Effect bleedingSet(Skills::SkillStruct::EffectsStruct::bleeding  in){
    auto b=static_cast<Skills::SkillStruct::Effect*>(&in);
    auto c=*b;

Ответы (2 шт):

Автор решения: Yaroslav Fyodorov

У вас тут очень накручено, но по сути, у вас есть class A: B, C {} т.е объект, в котором есть и поля B и поля C. Дальше вы берете указатель,на B и делает на него указатель на A, которым он не является. Дальше естественно ничего не работает. И непонятно почему вы используете static_cast для кастинга классов? Используйте dynamic_cast<A*>(ptr) и он честно вернет null, когда не сможет сделать cast.

→ Ссылка
Автор решения: AlexGlebe

так как вы передаёте аргумент по значению (Skills::SkillStruct::EffectsStruct::bleeding in), преобразование типа не сможет объект привести к другому типу которого вообще нет. происходит исключение при работе с выдуманным объектом типа Skills::SkillStruct::Effect

преобразование указателя на объект сына должно работать, если вы сначала создали сына, потом передали указатель на папу, потом опять указатель на сына. Но так как вы послали в функцию копию базового класса без сына, то из копии предка вы сына не получите.

class B{};

class S:public B{};

void fun(B b) {
  // b - это копия объекта базового класса
  // сына там нет
  S * p = static_cast<S*>(&b);
  // указатель p указывает на несуществующий объект
  }

 int main() {
   S s;
   fun(s); }

чтобы всё работало, нужно передавать аргумент не копией, а ссылкой.

void fun(B & b) {
  // b - это ссылка на объекта базового класса
  // указатель на сына можно получить
  S * p = static_cast<S*>(&b);
  // указатель p указывает на реальный объект
  // только если вы передавали объект типа S
  }
→ Ссылка