Доступ к переменной-члену через родительский класс и смещение - PullRequest
0 голосов
/ 30 ноября 2018

Я поставил тег language lawyer, хотя у меня такое ощущение, что это не с той стороны стандартной границы.Я не видел разговоров именно по этому вопросу, но у меня был на работе, поэтому я хотел бы иметь определенную уверенность по этому поводу.

Проблема заключается в доступе (потенциально) частные поля виртуальных базовых классов.Скажем, я вычисляю смещение частного поля класса, а затем использую это смещение вне класса для доступа (чтения / записи) к переменной-члену в этом месте.

Я видел, что есть расширение для GCCи clang offsetof (этот условно определен в C ++ 17, что это значит?), и его использование эквивалентно некоторой арифметике указателей, подобной этой:

#include <iostream>

class A
{
    int a{};
public:
    int aa{};
    static ptrdiff_t getAOffset()
    {
        A instance;
        return reinterpret_cast<ptrdiff_t>(static_cast<const void*>(&instance)) - reinterpret_cast<ptrdiff_t>(static_cast<const void*>(&(instance.a)));
        //return offsetof(A, a); // "same" as this call to offset
    }

    int get() const
    {
        return a;
    }
};

class B: public virtual A
{
};

void update_field(char* pointer, ptrdiff_t offset, int value)
{
    int* field = reinterpret_cast<int*>(pointer + offset);
    *field = value;
}

void modify_a(B& instance)
{
    update_field(reinterpret_cast<char*>(dynamic_cast<A*>(&instance)), A::getAOffset(), 1);
}

int main()
{
    B instance;

    std::cout << instance.get() << std::endl;

    modify_a(instance);

    std::cout << instance.get() << std::endl;
}

Я также сделал coliru(педантичный), который не жалуется, но все же ... https://coliru.stacked -crooked.com / a / faecd0b248eff651

Есть ли в стандарте что-то, разрешающее это, или это внеопределенное поведение земли?Рад также видеть, есть ли разница между стандартами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...