Значение является абстрактным понятием.Значение связано с набором реализаций, которые характеризуют или идентифицируют значение.Например, со значением 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;
}
2*argc
встроенный оператор * вызывается с двумя аргументами 2
и argc
.argc
является lvalue, поэтому применяется lvalue-to-rvalue .Значение argc
равно загружено в регистр процессора (2 может быть немедленный ) и операция multiply
выполняется. - результат
2*argc
является prvalue, который непосредственно используется в качестве первого операнда (2*argc)+(argc)
.Затем полученное значение этой последней операции используется для инициализации объекта j
: результирующее значение сохраняется в представлении памяти j
.