Stepanov给出了以下值语义的定义(他称之为常规类型)
T a = b; assert(a == b); // 1
T a; a = b; assert(a == b); // 2
T a = c; T b = c; a = d; assert(b == c); // 3
T a = c; T b = c; zap(a); assert(b == c && a != b); // 4
即,具有值语义的类型是 DefaultConstructible、CopyConstructible、Assignable 和 EqualityComparible(属性 1 和 2)。此外,
c
在为a
和分配相同的值之后b
,我们希望能够在a
不更改b
(property 3) 的值的情况下进行修改。ifzap
是一个总是改变其操作数的值的操作,我们期望b
并且c
不会仅仅因为它们的值随着 's 一起改变而继续相等a
,而是因为改变a
's 的值并没有改变它们的值(属性 4)。
具有引用语义的类型可以遵循 1 和 2,但不能遵循 3 和 4(即修改指向或引用相同值的多个对象之一,会影响所有对象)。
所有内置类型都遵循值语义并且修改是本地化的。这使得它们例如非常适合纯函数和并行编程。使用引用语义(例如具有虚拟功能的对象),更改不再是本地化的。
T* a = c; T* b = c; a = d; assert(b == d); // 5
T* a = c; T* b = c; zap(a); assert(b != c && a == b); // 6