Question 1: why isn't there a keyword?
No-one apart from Stroustrup or the committee members can really answer why C++ is how it is, but we can speculate, probably that it wasn't considered important enough for a keyword. The C++ standard does talk about order of initialization, such as for objects but the order is not strictly defined and left to the implementation. Here's one quote (3.6.2/3):
It is implementation-defined whether
or not the dynamic initialization
(8.5, 9.4, 12.1, 12.6.1) of an object
of namespace scope is done before the
first statement of main. If the
initialization is deferred to some
point in time after the first
statement of main, it shall occur
before the first use of any function
or object defined in the same
translation unit as the object to be
initialized
Question 2: how to achieve the equivalent of the Delphi initialization
and finalization
keywords?
There are two options. The first has been mentioned by other posters and I don't want to copy their answers: declare an object in a certain scope (translation unit or namespace) and its constructor and destructor will be called 'sometime'; do work there.
Note that the order of this is implementation-defined, so you're already in uncertain territory.
The second option is also compiler dependent. You're using Delphi, so am I right in thinking you're using C++ Builder to compile your C++ code? If so, C++ Builder and some other compilers support the #pragma startup
and #pragma exit
pragmas. These pragmas call a method at a certain time when your program is starting up or shutting down.
Personally I find this a neater solution, for two reasons:
It specifies exactly when something
will occur and I can see it written
down in code
It allows you to call a
function, instead of using a
constructor or destructor. This is
aesthetically cleaner and lets you write, say,
initialization()
and finalization()
methods which
perform your work. This probably gets you as close to the Delphi syntax as you can get.
You can use these pragmas to call a procedure (which takes no parameters and returns void) and also optionally specify when it should occur, using a number between 64 and 255. You need to do this only if the order of initialization or finalization matters. A higher number is called first and priorities of 0-63 are reserved. For example:
void initialization(void) { foo = 3; bar = 5; /* Do useful work here */ }
#pragma startup initialization 200
void finalization(void) { foo = 0; bar = 0; /* Do useful work here */ }
#pragma exit finalization 200
The call chain is managed by the linker and you can run into issues if you use more compiler-specific constructs, such as weak packaging, but in general this is the technique I would recommend.