C++

In C++, a fundamental design principle is that built-in types like int should not behave any differently from user-defined types like Dog. The word “object” simply refers to “some memory that holds a value of some type,” [1] which includes the built-in types.

By default, variables refer to the value of an object, and those values get copied by function/constructor call, return, assignment, or exception [1].

int i {5}; int i2 = i; // copy
Dog d {"Fido"}; Dog d2 = d; // copy

If you want the memory address of an object (a “pointer” to the object), you have to ask for it with the address-of operator &. A pointer to an object of type T has type T* (“T-star”). You can de-reference with * to get the value pointed at, or use -> instead of . to access a class member through a pointer.

int i {5};
int* i2 = &i; // no copy
cout << *i2; // outputs 5

Dog d {"Fido"};
Dog* d2 = &d; // no copy
d2->bark(); // same as (*d2).bark(); (neither makes a copy)

In addition to pointers, C++ also has references. They can be thought of as variable synonyms. Like pointers, references are used to avoid making copies by assignment or function call. Simple example:

int x = 10;
int& y = x; // y is a reference to x
y = 5; // equivalent to setting x = 5
cout << x; // outputs 5
A function call example:
int x=10;
void change_variable(int& y) {
	y = 5;
}
change_variable(x);
cout << x; // outputs 5
Unlike pointers, references cannot be null. They must be initialized with a reference to an object. Also unlike pointers, references cannot be changed to refer to a different object after they are initialized.

References may be implemented with pointers by the compiler, but this is not specified.