C ++ присваивает постоянную ссылку на переменную экземпляра (проблемы с памятью?)

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

Но сегодня я увидел этот код и не понимаю, почему он правильный:

Есть простая структура, Color3B. Мы создаем один в стеке так:

Color3B color(255,0,0);

Есть еще один класс, одна из его переменных экземпляра имеет тип Color3B.

class Node{

private:
Color3B _color;
public:
void setColor(const Color3B& color){
_color = color;
}
};

Использование:

void someFunction(){
Color3B color(255,0,0);
_someNode->setColor(color);
}

Я думаю, что цвет разрушается, когда он выходит за рамки: когда завершается некоторая функция. Но setColor получает адрес памяти чего-либо, созданного в стеке, и сохраняет его. Но нет никаких проблем, когда я получаю доступ к _color узла, он всегда там и имеет правильное значение.

Что мне здесь не хватает?

0

Решение

_color = color; принимает значение копии color так что не важно, что color в конце концов выходит за рамки.

У вас будут проблемы, если переменная-член _color было сам ссылка.

3

Другие решения

void someFunction(){
Color3B color(255,0,0);    // (1)
_someNode->setColor(color);// (2)
}                              // (5)void setColor(const Color3B& color){ // (2)(3)
_color = color;                  // (4)
}

Давайте посмотрим, что здесь происходит:

  1. создать объект с именем color
  2. дать ссылку на setColor
  3. параметр color теперь ссылка (псевдоним) color
  4. скопировать значение color в _color (назначение), потому что _color не ссылка
  5. color уничтожен
0

Ошибка, которая, по вашему мнению, должна произойти, произойдет, если _color была ссылка.

class Node{

private:
const Color3B& _color;
public:
void setColor(const Color3B& color){
_color = color;
}
};

Этот код выдаст ожидаемую ошибку. Теперь вы фактически сохраните адрес цвета в стеке в Node и это будет уничтожено в конце someFunction(), Однако вы этого не делаете. Ваш Node имеет свой Color3B объект, а не ссылка на него. Итак, код _color = color на самом деле выполняет копию из цвета в someFunction() к цвету в Node объект. Теперь, даже если исходный цвет будет уничтожен, один в Node Живет на.

Если вы написали setColor() с указателем эквивалент вашего кода будет:

void setColor(const Color3B* color){
_color = *color;
}

Потому что ссылка — это не адрес переменной, а псевдоним. Так color в приведенном выше коде (если это ссылка) представляет значение его, а не адрес. Чтобы получить адрес, вам нужно написать &color,

0
По вопросам рекламы [email protected]