Const ссылки на членов безопасны

Если я использую постоянную ссылку на другого участника,
Возможно ли, что эта ссылка становится недействительной?

class Class {
public:
const int &x{y};
private:
int y;
};

Например, когда я использую экземпляры этого класса в векторе
который увеличивает его емкость после push_back,
Согласно стандарту все итераторы и ссылки становятся недействительными, если
вектор должен увеличить свою емкость. Ссылка остается в силе после этого?

5

Решение

В настоящее время это небезопасно, например, когда вы копируете экземпляр Class, x будет ссылаться на y скопированного объекта, а не его собственного y, Вы можете увидеть это, запустив следующий код:

int main()
{
Class a{};
std::vector<Class> vec;
vec.push_back(a);

//these lines print the same address
std::cout << &(a.x) << std::endl;
std::cout << &(vec[0].x) << std::endl;
}

Вы можете исправить это, написав свой собственный конструктор копирования и функции присваивания для правильной инициализации x:

Class (const Class& rhs) : x{y}, y{rhs.y} {}

Это безопасно, потому чтоx а также y будет уничтожен только вместе с вашим объектом. Аннулирование ссылок на std::vector означает ссылки на элементы вектора:

Class c;
std::vector<Class> vec;
vec.push_back(c);

Class& cr = vec[0];
//other operations on vec
std::cout << c.x; //fine, that reference is internal to the class
std::cout << cr.x; //cr could have been invalidated
7

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

Предполагая, что это ссылка на другой член из того же экземпляра, вам нужно переопределить конструктор копирования, чтобы инициализировать его. Конструктор копирования по умолчанию скопирует ссылку на ‘y’ из старого экземпляра, который может быть признан недействительным.

Зачем вам ссылка на участника это другой вопрос.

Постскриптум Также вам необходимо переопределить оператор присваивания по той же причине.

3

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