value semantics
When you photocopy a document and hand someone the copy, your edits to your original do not change their copy, and theirs do not change yours — the two are now independent. That is value semantics: a variable holds its own value, and assigning or passing it makes an independent copy. Contrast it with reference or pointer semantics, where two names refer to the same underlying object, so a change through one is visible through the other (like sharing one document by reference rather than copying it).
In C++, by default objects have value semantics. If you write Widget b = a; you get a second, independent Widget — b's data is copied from a, and later changing b leaves a untouched. A reference (Widget& r = a;) or a pointer (Widget* p = &a;) gives you the opposite: r and *p are just other names for a, and modifying through them modifies a. The whole machinery of copy constructors, move operations, and the special member functions exists precisely to define what 'make an independent copy of this value' means for your type.
Why this matters: value semantics make code dramatically easier to reason about because there is no spooky action at a distance — a function that takes its argument by value cannot mutate your object, and two distinct values cannot alias. This is also why std::vector and std::string copy their contents on assignment. The honest trade-off is cost: copying a large object is real work, which is exactly the problem that move semantics was invented to relieve. C programmers feel this when they pass a struct by value (a full copy) versus a pointer to it (sharing) — C++ formalizes and extends that choice.
std::vector<int> a{1,2,3}; auto b = a; b.push_back(4); // a is still {1,2,3}; b is {1,2,3,4} — independent copies
Assignment copies the value; with a reference or pointer instead, modifying b would have changed a.
Value semantics is the default but not automatic for correctness: if your class holds a raw owning pointer and you do nothing, the compiler's default copy duplicates the pointer (a shallow copy), so two objects own the same memory and double-free it. Defining copy correctly — or using RAII members — is what makes value semantics actually safe.