C++ constructor, destructor and class
C++ introduces innovations such as constructor, destructor and class.
This article is part of a series on the history of regular data type in C++.
C++ introduced next a lot of innovations on top the C struct
. All these
improvements went through several iterations to become today’s equivalents. I’m
going to provide today’s equivalents, though the tools did not simply became
their current incarnation.
Constructor, destructor
First it introduced the idea of a member function. A member function gets a
pointer to the instance as a hidden first argument (usually), called this
.
1
2
3
4
5
6
7
8
9
struct foo {
// member variable
int bar;
// member function
void buzz() {
// member function body
}
};
In the member function body you can access members either directly (e.g. bar =
42
) or via the this
pointer (e.g. this->bar = 42
).
The constructor syntax is to declare a member function with the same name as
the struct
and no return type. The destructor is similar, but preceded by
~
. ~
was/is the bitwise NOT, someone thought it’s a funny pun that the
destructor is “NOT constructor”.
1
2
3
4
5
6
7
8
9
10
11
12
struct foo {
// constructor
foo() {
// constructor body
}
// destructor
// "not constructor"
~foo() {
// destructor body
}
};
The constructor and destructor allow for initialisation and cleanup. They apply automatically when an instance of the class is created or destructed. That is a big step forward compared with the DIY approach in C where the programmer has to remember to call equivalent functions manually.
Constructor has more facilities that the destructor, such that you can have function parameters, hence you can have multiple constructors that differ in the parameters they take. Also constructors have additional syntax to do initialization before the function body.
The constructor/destructor are particularly useful when they involve some resource, even something as simple of memory allocated on the heap. They allow for the RAII idiom: allocate in the constructor, free in the destructor.
1
2
3
4
5
6
7
8
9
10
11
struct foo {
bar * ptr;
foo() {
// allocate memory here
}
~foo() {
// deallocate memory here
}
};
This pattern is particularly useful for dynamically sized containers. Due to their variable size the content can’t be stored directly in the object, so they often allocate on the heap and store pointer(s) to the allocated data. The member variables of the class are local parts, at constant offset from the address of the object itself, while the pointed data are remote parts.
Class vs. struct
You might not want the user of the class to accidentally change the pointer
member, this leads to public
, private
and protected
in C++ that control
visibility from the outside of the class.
class
is really the same as as struct
in C++, except the default visibility
which is private
for class
.