Как обратится к полю конкретного прародителя из наследника?

Вот код описывающий суть моей проблемы:

#include <iostream>

struct parent
{
    int quality = 1;
};

struct succesor : parent
{
    int quality = 2;
};

struct grandsuccesor : succesor
{
    int quality = 3;
};


int main()
{
    grandsuccesor example;
    std::cout << example.quality << std::endl << sizeof(example);
}

Вывод программы:

3
12

То есть поле example.quality выбирается из самого класса, а не родителя. Но как обратится конкретно, допустим, к полю parent quality? Ведь sizeof(example) = 12, а значит все таки выделяется 3 различных переменных. А как обратится к каждому из них?


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

Автор решения: HolyBlackCat
std::cout << example.parent::quality << '\n';
std::cout << example.succesor::quality << '\n';

А если написать example.grandsuccesor::quality, то это будет эквивалентно просто example.quality.


Есть еще вариант - скастовать класс в ссылку на родителя, и обратиться к полю:

static_cast<parent &>(example).quality

Методы так тоже можно вызывать.

Но у первого способа есть особенность - он игнорирует виртуальность методов. То есть если написать x.Родитель::Метод(), то вызовется именно метод родителя, даже если он виртуальный и был переопределен.

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

Можно обратиться путем частичного разыменования:

int main()
{
    grandsuccesor example;
    succesor *ptr_succesor = &example;
    parent *ptr_parent = &example;
    std::cout << example.quality << std::endl << ptr_succesor->quality << std::endl << ptr_parent->quality;
}
→ Ссылка