Every object type has a constructor—else how would you construct it?—and a destructor—else how would it be destroyed? They don’t “get in the way” of anything, because the default implementations are no-ops in the case of POD-only fields, just as if you had said:
struct f {
f() {}
~f() {}
int a, b, c, d;
};
However, if you write an empty constructor, the type becomes non-POD. C++11 solves this with defaulting:
f() = default;
~f() = default;
The situation is slightly different with copy constructors, where the implicitly generated one is just a convenience that does “the right thing” for POD types:
f(const f& other) : a(other.a), b(other.b), c(other.c), d(other.d) {}
There is no reason to rewrite this yourself. If you want to make a type noncopyable, you can mark the copy constructor as deleted with f(const f&) = delete;
or declare it private
.
It’s also important to note that member functions are not stored on the object as member variables are. You can think of a class
or struct
as simultaneously two things:
A description of a data layout
A namespace containing functions and types for manipulating that data
The C++ model of object-oriented programming simply couples these two things in one place.