“Constructors” for built-in types
As the language developed and more effort
was put into making user-defined types look like
built-in types, it became apparent that there were times
when it was helpful to make built-in types look like user-defined types. In the
constructor initializer list, you can treat a built-in type as if it has a
constructor, like this:
//: C08:BuiltInTypeConstructors.cpp
#include <iostream>
using namespace std;
class B {
int i;
public:
B(int ii);
void print();
};
B::B(int ii) : i(ii) {}
void B::print() { cout << i << endl; }
int main() {
B a(1), b(2);
float pi(3.14159);
a.print(); b.print();
cout << pi << endl;
} ///:~
This is especially critical when
initializing const data members
because
they must be initialized before the function body is entered.
It made sense to extend this
“constructor” for built-in types (which simply means assignment) to
the general case, which is why the float pi(3.14159) definition works in
the above code.
It’s often useful to encapsulate a
built-in type inside a class to guarantee initialization with the constructor.
For example, here’s an Integer class:
//: C08:EncapsulatingTypes.cpp
#include <iostream>
using namespace std;
class Integer {
int i;
public:
Integer(int ii = 0);
void print();
};
Integer::Integer(int ii) : i(ii) {}
void Integer::print() { cout << i << ' '; }
int main() {
Integer i[100];
for(int j = 0; j < 100; j++)
i[j].print();
} ///:~
The array of Integers in
main( ) are all automatically initialized to zero. This
initialization isn’t necessarily more costly than
a for loop or memset( ). Many
compilers easily optimize this to a very fast
process.