value (Справочник по C#)
Контекстное ключевое слово value используется в методе доступа set в объявлениях свойства и индексатора. Оно аналогично входному параметру метода. Ключевое слово value ссылается на значение, которое клиентский код пытается присвоить свойству или индексатору. В приведенном ниже примере класс MyDerivedClass имеет свойство с именем Name , в котором используется параметр value для присвоения новой строки резервному полю name . С точки зрения клиентского кода эта операция выглядит как простое присвоение.
class MyBaseClass < // virtual auto-implemented property. Overrides can only // provide specialized behavior if they implement get and set accessors. public virtual string Name < get; set; >// ordinary virtual property with backing field private int _num; public virtual int Number < get < return _num; >set < _num = value; >> > class MyDerivedClass : MyBaseClass < private string _name; // Override auto-implemented property with ordinary property // to provide specialized accessor behavior. public override string Name < get < return _name; >set < if (!string.IsNullOrEmpty(value)) < _name = value; >else < _name = "Unknown"; >> > >
Дополнительные сведения см. в статьях Свойства и Индексаторы.
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
тег документации
Тег позволяет описать методы доступа к свойству и свойствам. При добавлении свойства с помощью мастера кода в интегрированной среде разработки Visual Studio он добавит тег для нового свойства. Необходимо вручную добавить тег, чтобы описать значение, которое представляет свойство.
Синтаксис
/// property-description
Параметры
property-description
Описание свойства.
Замечания
Скомпилируйте их для /doc обработки примечаний документации к файлу.
Пример
// xml_value_tag.cpp // compile with: /LD /clr /doc // post-build command: xdcmake xml_value_tag.dll using namespace System; /// Text for class Employee. public ref class Employee < private: String ^ name; /// Name accesses the value of the name data member public: property String ^ Name < String ^ get() < return name; >void set(String ^ i) < name = i; >> >;
См. также
Обратная связь
Были ли сведения на этой странице полезными?
Семантика перемещения
В С++ используемые значения мы можем разделить на две группы: lvalue и rvalue . lvalue представляет именованное значение, например, переменные, параметры, константы. С lvalue ассоциирован некоторый адрес в памяти, в котором на постоянной основе хранится некоторое значение. И мы можем lvalue присвоить некоторое значение. А rvalue — это то, что можно только присваивать, например, литералы или результаты выражений. Например:
int n = 5;
Здесь n представляет lvalue, а число 5 — rvalue. Подобные названия приняты, потому что n расположен слева от оператора присваивания (left value), а присваиваемое значение — число 5 справа от оператора присвоения (right value). Другой пример:
int n int k;
Здесь n и k — lvalue, а 5 и выражение n + 7 — rvalue.
rvalue-ссылка
rvalue-ссылка может ссылаться на результат выражения, даже если этот результат представляет временное значение. Привязка к rvalue-ссылке продлевает время жизни такого временного значения. Его память не будет удалена, пока rvalue-ссылка находится в области видимости.
Для установки ссылки rvalue применяются два амперсанда после имени типа:
#include int main() < int n ; int&& tempRef ; // ссылка rvalue std::cout
В данном случае результат выражения n+3 сохраняется в памяти (в стеке), а ссылка tempRef будет представлять ссылку на это временное значение. Когда завершится функция main, соответственно завершится и область видимости переменной tempRef и будет удалено временное значение, на которое эта переменная ссылается. Стоит отметить, что tempRef, хоть и хранит ссылку на rvalue, само по себе также является lvalue.
Функция std::move
Стоит отметить, что мы не можем установить ссылку rvalue на значение lvalue, например:
int n ; int&& tempRef = n; // ! Так нельзя
Здесь n - lvalue, а ссылке rvalue мы можем только передать значение rvalue. Тем не менее в некоторых ситуациях может возникать необходимость преобразовать lvalue в rvalue. Для этого применяется встроенная функция std::move() , которая имеется по умолчанию в стандартной библиотеке C++:
#include int main() < int n ; int&& tempRef = std::move(n); // преобразуем int в int&& std::cout
Здесь значение переменной n преобразуется из типа int в тип int&& - rvalue-ссылку на int. В данном случае практического смысла в подобном преобразовании мало, но далее на примере конструктора перемещения мы посмотрим реальную пользу подобной функции.
Также стоит обратить внимание, что при преобразовании константного значения результатом является константная ссылка:
const int m; const int&& mRef = std::move(m); // результат - константная ссылка
rvalue-ссылка как параметр функции
rvalue-ссылка может выступать в качестве параметра функции.
#include void print(std::string&& text) < std::cout int main()
Чтобы указать, что параметр представляет rvalue-ссылку, после типа указываются два амперсанда &&. То есть здесь функция print принимает rvalue-ссылку на значение std::string. При вызове этой функции ей можно передать rvalue:
print("hello");
Но нельзя передать lvalue, поэтому следующие строки НЕ скомпилируются:
std::string message = "hi world"; print(message); // ! Ошибка - передаем lvalue
Однако мы могли бы применить опять же функцию std::move() и преобразовать переменную в rvalue:
print(std::move(message));
Возвращение rvalue из функции
При возвращении значения локальной переменной или параметра компилятор рассматривает значение как rvalue. Но если возвращаемое значение представляет переменную компилятор также может выполнять оптимизацию NRVO (named return value optimization):
#include void print(std::string&& text) < std::cout std::string defaultMessage() < std::string message; return message; > int main() < print(defaultMessage()); // передаем rvalue >
Здесь функция defaultMessage возвращает rvalue, соответственно результат этой функции мы можем передать внутрь функции print. Применяемая оптимизация NRVO означает, что компилятор сохраняет объект результата непосредственно в памяти, предназначенной для хранения возвращаемого функцией значения. То есть после применения NRVO больше не выделяется память для отдельной автоматической переменной с именем message. То есть при выполнении этой программы создается только один объект std::string .
Аналогично происходит при сохранении во внешнюю переменную:
#include std::string defaultMessage() < std::string message; return message; > int main()
Здесь также создается только один объект std::string.
Эта была вводная информация про значения rvalue и как с ними работать. В следующих статьях посмотрим, где в применяется в практическом плане.
Что такое rvalue и lvalue?
На разных ресурсах нашел разные определения rvalue , lvalue . Как же правильно? right value или read value ? left value или locator value ?
Отслеживать
29k 14 14 золотых знаков 61 61 серебряный знак 119 119 бронзовых знаков
задан 2 авг 2018 в 10:03
2,904 20 20 серебряных знаков 45 45 бронзовых знаков
Правильно left и right
2 авг 2018 в 10:22
Никак не правильно, это не расшифровывается. Но произошло от right и left.
2 авг 2018 в 10:26
На мой взгляд, правильный первый вариант, так как взять к примеру простое выражение: a = b + c ,где (a = lvalue), a (b + c = rvalue). Судя по примеру lvalue подразумевает как бы left, но никак не read, тоже самое можно сказать и про rvalue.
2 авг 2018 в 11:22
О чем вопрос вообще? Почему в заголовке речь идет о "rvalue and lvalue references", а в теле вопроса ни слова про references нет и идет речь просто о rvalue и lvalue? В качестве "принятого" выбран ответ, который к "rvalue and lvalue references" вообще не имеет никакого отношения. Что за бессмысленная каша?
2 авг 2018 в 14:32
@Dima Khodan: Нет. Основным критерием качества вопросов (и ответов) на SO являются их полезность для последующих читателей. Если заголовок вопроса никак не соответствует его содержанию, то ценность вопроса - "ниже плинтуса" и он подлежит правке или удалению. Ваше "тут все прекрасно поняли суть" никакого значения не имеет. Я еще раз повторю: почему в заголовке речь идет о "references"? Если ваш вопрос не имеет никакого отношения к "references", то - исправляйте заголовок.
2 авг 2018 в 21:39
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Исходно речь шла про правую и левую части относительно оператора присваивания. Но правильного варианта такой простой расшифровки нет и быть не может. Термины так и останутся rvalue и lvalue . А вот какой в них вложен смысл чётко прописано в стандарте. Всё это образует категории выражений.
- glvalue (“generalized” lvalue) Выражение, чьё вычисление определяет сущность объекта, битового поля или функции.
- prvalue (“pure” rvalue) Выражение, чьё вычисление инициализирует объект, битовое поле или вычисляет значение операнда оператора, с соответствии с контекстом использования. Например, литералы 42 , true , nullptr за исключением строковых литералов, которые являются lvalue выражениями.
- xvalue (“eXpiring” lvalue) Это glvalue, которое обозначает объект или битовое поле, чьи ресурсы могут быть повторно использованы (обычно потому, что они находятся около конца своего времени жизни). Например, результат вызова std::move даёт выражение xvalue.
- lvalue Это glvalue, которое не является xvalue. Например, имя переменной, функции или члена-данных, независимо от их типа, даже переменная, имеющая тип rvalue-ссылки, образует выражение lvalue.
- rvalue Это prvalue или xvalue.
Таким образом любое выражение есть в первую очередь lvalue, xvalue или prvalue. rvalue - это уже обобщение.
Отслеживать
ответ дан 2 авг 2018 в 10:27
29k 14 14 золотых знаков 61 61 серебряный знак 119 119 бронзовых знаков
Только вопрос такой. Что значит неполный тип?
2 авг 2018 в 12:04
@DimaKhodan A class that has been declared but not defined, an enumeration type in certain contexts (9.6), or an array of unknown bound or of incomplete element type, is an incompletely-defined object type. Incompletely-defined object types and cv void are incomplete types (6.7.1). Objects shall not be defined to have an incomplete type.
2 авг 2018 в 12:48
Не знаю, что Вы имеете ввиду под вопросом "как правильно". rvalue и lvalue - это категории выражений. Вот что написано в стандарте:
— A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
— A prvalue is an expression > whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
— An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime).
— An lvalue is a glvalue that is not an xvalue.
— An rvalue is a prvalue or an xvalue.//.
[Note: Historically, lvalues and rvalues were so-called because they could appear on the left- and right-hand side of an assignment (although this is no longer generally true); glvalues are “generalized” lvalues, prvalues are “pure” rvalues, and xvalues are “eXpiring” lvalues. Despite their names, these terms classify expressions, not values. — end note]