C++ defines for you a copy constructor, an assignment operator and a move constructor if this can be done trivially; in these cases you should have to do nothing, just return an object instance and the caller will get it.
If the object has however some parts that cannot be copied (for example references) then you need to provide copy constructors and assignment yourself (but may be the class indeed shouldn't be copied or assigned).
There are also other limitations that prevent automatic synthesis of the move constructor (to avoid bugs).
Note also that there are cases in which the C++ compiler will synthesize copy constructor and assignment, but using wrong code. You need to be careful (for example if the class contains naked owning pointers).
For a simple case in which everything works out of the box with no need to do anything consider:
// A bi-dimensional point
struct P2d {
double x, y;
};
// Computes the middle point given two points
P2d average(P2d a, P2d b) {
return P2d{(a.x+b.x)/2, (a.y+b.y)/2};
}
As you see nothing is needed in the class to support returning P2d values or accepting P2d parameters.
The compiler in that case automatically completes the definition code to something like:
struct P2d {
double x, y;
P2d(const P2d& other)
: x(other.x), y(other.y)
{
}
P2d& operator=(const P2d& other) {
x = other.x;
y = other.y;
return *this;
}
~P2d() {
}
};