Значение против объекта - PullRequest
0 голосов
/ 24 декабря 2018

[C ++ 17]

Когда вычисляется выражение prvalue, стандарт говорит, что оно приводит к значению.В случае 5 выражение является prvalue, и оно оценивается как значение 5.

Однако, когда у вас есть prvalue, в основном инициализатор для объекта, такой как Foo{}.Какова будет ценность этого выражения?Будет ли результат временным объектом, созданным преобразованием prvalue-xvalue?Это поднимает мой более широкий вопрос о разнице между значением и объектом .

Ответы [ 3 ]

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

Значение - это понятие;объект - это вещь на всю жизнь.Это различие имеет тенденцию быть гораздо более важным для типов классов со сложными конструкторами, но правила применяются одинаково ко всем типам.

Рассмотрим эту простую программу:

std::string foo() { return std::string{"Hello"}; }

int main() {
    std::string f = foo();
}

foo не создаетобъект.Создание объекта потребовало бы вызова конструктора класса, чтобы начать жизнь объекта.Для std::string это, вероятно, потребует выделения памяти и копирования символов, и по довольно очевидным причинам мы хотели бы избегать этого слишком много раз.

Вместо этого foo возвращает значение.Он возвращает концепцию «строки, инициализированной символами« Hello »».В конце концов, main может взять эту абстрактную концепцию и построить объект для представления этого значения.Из-за этого различия создается только один объект, поэтому дополнительные затраты на начало и конец времени жизни объекта должны быть оплачены только один раз.

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

Значение является абстрактным понятием.Значение связано с набором реализаций, которые характеризуют или идентифицируют значение.Например, со значением 10 $ можно купить книгу или еду.

Значение может иметь несколько представлений.Например, 10 $ может быть представлено монетами или сохранено в виде битов на банковском счете.

объект соответствует значению , что банковский счет соответствует количеству денег : объект (/ банковский счет) содержит представление значения (/ 10 $).Это описано в [basic.types] :

Представление значения объекта типа T представляет собой наборбиты, которые участвуют в представлении значения типа T. Биты в представлении объекта, которые не являются частью представления значения, являются битами заполнения.

Затем в [intro.object] указывается, что объект связан с областью хранения:

Объект занимает область хранения в период его строительства ([class.cdtor]), на протяжении всегоего время жизни и период разрушения ([class.cdtor]).

Это различие между объектом и его значением более разумно, если мы рассмотрим абстрактную машину сцентральный процессор, который выполняет операции, и отдельную память, где могут храниться объекты (которые содержат представление значений).Когда операция выполняется над значением, оно загружается в разные регистры процессора.Таким образом, значение в процессоре не имеет того же представления: непрерывная последовательность битов, как это было внутри объекта.Более того, любой процессор может свободно представлять значение в регистре как наиболее подходящее для его потребности.

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

Разложение операции в операциях со значениями и в хранилищах или загрузках из или вобъекты, отображаются в стандарте:

  • a load - это lvalue-to-rvalue преобразование [conv.lvalue] Значение не функционального типа, не являющегося массивом типа T, может быть преобразовано в значение типа prvalue.

  • все операции в c ++приведет к последовательности фундаментальных операций со встроенным значением .Большая часть этих операций применяется к значению (prvalue), а не к объекту.Перед выполнением этих операций применяется значение lvalue-to-rvalue [expr] Всякий раз, когда выражение glvalue появляется как операнд оператора, который ожидает значение для этого операнда,lvalue-to-rvalue, [...]

  • результаты этих встроенных операций, которые работают со значением, всегда являются prvalue (prvalue является просто значениемне связан ни с одним объектом).Затем полученное значение можно использовать как операнд другой встроенной операции или инициализировать объект (операция store в памяти нашей машины), [basic.lval] : prvalue - это выражение, вычисление которого инициализирует объект или битовое поле или вычисляет значение операнда оператора, как определено контекстом, в котором оно появляется. Таким образом, в нашем машинном представлении актом сохранения значения в объекте является хранилище.

Чтобы проиллюстрировать это, давайте проанализируем этот простой фрагмент кода:

int main(int argc, char* argv[]){
  int j = 2*argc+1;
  }
  1. 2*argc встроенный оператор * вызывается с двумя аргументами 2 и argc.argc является lvalue, поэтому применяется lvalue-to-rvalue .Значение argc равно загружено в регистр процессора (2 может быть немедленный ) и операция multiply выполняется.
  2. результат 2*argc является prvalue, который непосредственно используется в качестве первого операнда (2*argc)+(argc).Затем полученное значение этой последней операции используется для инициализации объекта j: результирующее значение сохраняется в представлении памяти j.
0 голосов
/ 24 декабря 2018

[intro.object] / 1 :

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

Независимо от того, имеет ли prvalue тип класса, такой как Foo{} или нет, как литерал 5, считается значением, и это значение затем используется для инициализации объекта, если это действительно необходимо,это когда значение материализуется в объект.

[class.teven] / 2:

Материализация объектавременный объект, как правило, задерживается как можно дольше, чтобы избежать создания ненужных временных объектов.

В этом же разделе вы найдете список, описывающий материализацию временных времен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...