Не совсем понимаю, что адрес & оператор делает в этой структуре и как он может получить доступ к другим переменным-членам - PullRequest
1 голос
/ 28 мая 2019

Я начинаю разбираться с c ++, и я подумал, что смогу научиться создавать векторы и манипулировать ими, и при этом я буду разбираться с указателями и ссылками.Может быть, я смотрю на это слишком долго, но я не совсем уверен, что происходит с разделом кода, связанным с оператором return с книгой, за которой я следую, дал мне, более конкретно return ((&x)[i]);часть.Перечислено ниже:

float& operator [](int i)
{
    return ((&x)[i]);
}

Насколько я понимаю, & - оператор адреса выдаст вам адрес конкретной переменной.Теперь, если я правильно помню, указатели и массивы идут рука об руку, поэтому, когда вы получаете ссылку на переменную x, например, (&x)[i], вы можете получить доступ к следующему элементу, используя оператор смещения, но я не знал, что вы могли бысделать это со структурами.

Я на правильном пути или потерял его?

Используя следующие ссылки, чтобы помочь мне: http://www.cplusplus.com/doc/tutorial/pointers/ https://en.cppreference.com/w/cpp/language/operator_member_access

struct Vector3D
{
    float       x, y, z;

    Vector3D() = default;

    Vector3D(float a, float b, float c)
    {
        x = a;
        y = b;
        z = c;
    }

    float& operator [](int i)
    {
        return ((&x)[i]);
    }

    const float& operator [](int i) const
    {

        return ((&x)[i]);
    }
};

int main(int argc, char const *argv[])
{

    Vector3D vec = Vector3D(1,2,3);
    auto test = vec[1];
    std::cout << test << std::endl;

    return 0;
}

Я понимаю, что напечатанное здесь значение будет равно 2, но я не совсем получаю ссылку &x, способную получить доступ к значениям члена структуры?

1 Ответ

0 голосов
/ 28 мая 2019

Что

return ((&x)[i]);

делает, это берет адрес x, а затем, используя [i], получает объект со смещением i от x. По сути, вы притворяетесь, что у вас есть массив int вместо 3 отдельных int, где x является первым элементом массива.

Это неопределенное поведение по нескольким причинам. Во-первых, вы не можете получить доступ к элементу, который находится за пределами массива. Объект можно считать массивом из одного, поэтому (&variable)[0] является допустимым, поскольку это просто variable (игнорируя, что & может быть перегружено). Таким образом, любой индекс, кроме 0, является UB. Во-вторых, компилятору разрешено помещать заполнение между переменными-членами класса. Это означает, что вы не можете знать, не утверждая, что класс является ожидаемым размером, что y и z соседствуют с x в памяти.

Правильный способ написать функцию - использовать оператор switch, например

float& operator [](int i)
{
    switch(i)
    {
        case 0: return x;
        case 1: return y;
        case 2: return z;
        default: // throw an exception or return one of the members or do something else to indicate an error
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...