Order of construction

R

Raider

Are global objects always constructed in order of they declaration?

I use one global in the constructor of another one and I want to be sure
it works the same with any compiler. The code looks like this:

#include <iostream>

class Class1
{
public:
Class1() { std::cout << "Class1()" << std::endl; }
void Use() { std::cout << "Class1::Use()" << std::endl; }
};

Class1 Global1;

class Class2
{
public:
Class2() { Global1.Use(); }
};

Class2 Global2;

int main(int argc, char* argv[])
{
return 0;
}
 
S

Sumit Rajan

Are global objects always constructed in order of they declaration?

Yes. However, there is no guaranteed order of initialization of global
variables belonging to different translation units.

Regards,
Sumit.
 
B

Bob Hairgrove

Are global objects always constructed in order of they declaration?

Not necessarily, especially if they are defined in different source
files.
I use one global in the constructor of another one and I want to be sure
it works the same with any compiler. The code looks like this:

#include <iostream>

class Class1
{
public:
Class1() { std::cout << "Class1()" << std::endl; }
void Use() { std::cout << "Class1::Use()" << std::endl; }
};

Class1 Global1;

class Class2
{
public:
Class2() { Global1.Use(); }
};

Class2 Global2;

int main(int argc, char* argv[])
{
return 0;
}

In this case, I would create a struct which holds all the objects as
members declared in the order you need. The first time that the struct
is used after entering main(), the standard guarantees that it must
have been initialized. So when the struct is created, all of its
members get created in the correct order.
 
A

Alan Johnson

Raider said:
Are global objects always constructed in order of they declaration?

I use one global in the constructor of another one and I want to be sure
it works the same with any compiler. The code looks like this:

#include <iostream>

class Class1
{
public:
Class1() { std::cout << "Class1()" << std::endl; }
void Use() { std::cout << "Class1::Use()" << std::endl; }
};

Class1 Global1;

class Class2
{
public:
Class2() { Global1.Use(); }
};

Class2 Global2;

int main(int argc, char* argv[])
{
return 0;
}

Within the same translation unit objects are initialized in the order in
which they are defined. There is no guarantee on the initialization
order for objects in different translation units, and if I remember
correctly, deciding the correct order in the general case is an
unsolvable problem.

If you do, for whatever reason, find yourself needing to depend on the
intialization order of global variables in different translation units,
you can sidestep the problem by making your global variables static
members of functions. For example:

Class1 &GetGlobal1()
{
static Class1 Global1 ;
return Global1 ;
}

Class2 &GetGlobal2()
{
static Class2 Global2 ;
return Global2 ;
}
 
R

Raider

Alan, as I get you, the code must look like this (in case of multiple
files):

-- Class1.cpp ---
class Class1
{
public:
Class1() { std::cout << "Class1()" << std::endl; }
void Use() { std::cout << "Class1::Use()" << std::endl; }
static Class1 &GetGlobal();
};

Class1 &Class1::GetGlobal()
{
static Class1 Global1;
return Global1;
}

-- Class2.cpp ---
class Class2
{
public:
Class2() { Class1::GetGlobal().Use(); }
};

Class2 Global2;
 
A

Alan Johnson

Raider said:
Alan, as I get you, the code must look like this (in case of multiple
files):

-- Class1.cpp ---
class Class1
{
public:
Class1() { std::cout << "Class1()" << std::endl; }
void Use() { std::cout << "Class1::Use()" << std::endl; }
static Class1 &GetGlobal();
};

Class1 &Class1::GetGlobal()
{
static Class1 Global1;
return Global1;
}

-- Class2.cpp ---
class Class2
{
public:
Class2() { Class1::GetGlobal().Use(); }
};

Class2 Global2;


That should work. I personally wouldn't make the function a member of
the class (I'd just make it a standalone function), but that depends on
personal tastes and exactly what problem it is your are solving. The
point is that, unlike with global variables, you get to control when
initialization takes place. I think C++ guarantees that local static
objects are initialized the first time their definition is encountered
when executing the function.

Alan
 
R

Raider

Alan said:
That should work. I personally wouldn't make the function a member of
the class (I'd just make it a standalone function), but that depends on
personal tastes and exactly what problem it is your are solving.

All I want is to have a collection of classes derived from
SomeInterfaceClass and make this collection to be filled automaticaly
then SomeDerivedClass is linked to the project.

Like this:

---- HelperRegistratorClass.h ---
#include "..."
typedef SomeInterfaceClass *ObjCreator();
extern map<GUID, ObjCreator> ClassCollection;

class HelperRegistratorClass
{
public:
HelperRegistratorClass(GUID ClassID, ObjCreator Creator)
{
ClassCollection[ClassID] = Creator;
}
};

---- SomeDerivedClass.cpp ----
#include "..."

class SomeDerivedClass : public SomeInterfaceClass
{
public:
virtual void InterfaceFunction();
static const GUID ClassID = { ... };
static SomeInterfaceClass *Creator();
};

SomeInterfaceClass *SomeDerivedClass::Creator()
{
return new SomeDerivedClass();
}

HelperRegistratorClass SomeDerivedClassRegistrator
(
SomeDerivedClass::ClassID,
SomeDerivedClass::Creator
);

And I want ClassCollection to be constructed before any of
blabla-DerivedClassRegistrator-s.
 
I

iftekhar

could you make the collection call a singleton, for your problem i
guess it is OK
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top