Почему мы можем возвращать ссылки на переменные-члены класса - PullRequest
0 голосов
/ 02 декабря 2018

Я хочу понять, почему можно вернуть ссылку на переменную члена класса в C ++, например, в следующем примере:

class Foo
{
int x;
public:
int& get_pvar()
{
return x;
}};

По-видимому, мы можем получить доступ к переменной x в main (), создайте ссылку на него и затем измените его содержимое:

Foo obj;
int& ref = obj.get_pvar();
ref = 7;

Но как это возможно?x не имеет глобальной области видимости и не является статическим членом класса.Определяется в пределах класса.Таким образом, он должен иметь локальный охват.Итак, почему не является ошибкой возвращать ссылку на него и даже создавать ссылку на него в main ()?

Ответы [ 3 ]

0 голосов
/ 02 декабря 2018

«Область» и «контроль доступа» - это то, что относится к именам , а не к переменным.Сказать, что x является приватным в Foo, означает, что если мы напишем x в каком-то не связанном контексте, имя не будет найдено.

Но переменная все еще может быть доступна в других контекстах, если вам не требуется искать имя.

0 голосов
/ 02 декабря 2018

Вы путаете сферу и время жизни.Это две взаимосвязанные, но совершенно разные концепции.

Область действия name x - это область действия класса.Вы можете использовать только неквалифицированное имя x для члена внутри функций-членов (и некоторых других мелочей, не относящихся здесь) к классу.

время жизни объекта-члена с именем x такой же, как и вмещающий объект класса.В этом случае время жизни obj.x совпадает с obj.Поскольку вы возвращаете ссылку на объект в течение срока его службы, все проверяется.


Причина вашей путаницы может быть в том, что вы узнали, что объекты с автоматическим хранением, например, следующее:

{
    int x;
}

Срок их службы ограничен их лексической областью (они могут быть названы только внутри этих фигурных скобок, их области).Но хотя это верно для этих объектов, это не то, что в целом справедливо.Объекты класса могут жить независимо от области их имени (как вы видели).И некоторые объекты могут иметь время жизни, но не иметь области видимости и имени.Обратите внимание:

auto* p = new Foo();

Выражение new создает объект, но у него нет имени!Так что нет никаких оснований даже говорить о.Здесь p - имя указателя, а не вновь созданного объекта.

0 голосов
/ 02 декабря 2018

Так работают ссылки или указатели.Если вы решили экспортировать адрес своего личного поля, его можно изменить извне.

Это плохая практика, но в языке нет никакого механизма, который бы мешал разработчику делать это.

...