Connecting Tech Pros Worldwide Forums | Help | Site Map

Initialize static members outside the class

Steven Woody
Guest
 
Posts: n/a
#1: Jul 15 '08
Hi,

Supposing a class get a complicated static member foo, and it need to
be initialized before any method of the class can be called, where
should I put these initialization code? I don't want to put them in
main(), it's so far away.

Thanks.

-
narke

joseph cook
Guest
 
Posts: n/a
#2: Jul 15 '08

re: Initialize static members outside the class


On Tue, 15 Jul 2008 01:57:51 -0700, Steven Woody wrote:
Quote:
Quote:
Quote:
Hi,
>
Quote:
Quote:
Supposing a class get a complicated static member foo, and it need tobe
initialized before any method of the class can be called, where should
The question is how to define these initialise. *You know, for a
simple member, I can
do something like:
* *int MyClass::myMember = 123;
but for complicated non-POD types, such as a std::vector, how do I
initialize it by
push_back() many elements into it? * You see my problem? *Thanks.
Define in one place the same as you would the 'myMember' object.
Initialize in the constructor; that must be called before any methods
of the class.

Of course, you could just add the following:
std::vector<intNonPOD::foo(SIZE,4.4); // initialize to 4.4

Joe Cook


Lionel B
Guest
 
Posts: n/a
#3: Jul 15 '08

re: Initialize static members outside the class


On Tue, 15 Jul 2008 03:05:13 -0700, Steven Woody wrote:
Quote:
On Jul 15, 5:40 pm, Lionel B <m...@privacy.netwrote:
Quote:
>On Tue, 15 Jul 2008 01:57:51 -0700, Steven Woody wrote:
Quote:
Hi,
>>
Quote:
Supposing a class get a complicated static member foo, and it need to
be initialized before any method of the class can be called, where
should
>>
> ^^^^^^
>I presume you mean non-static method
>>
Quote:
I put these initialization code? I don't want to put them in main(),
it's so far away.
>>
>IIRC, a static class data member will be initialised before entering
>main(), so as long as you don't instantiate any class objects before
>entering main() you'll be ok*.
>>
>Then it depends how you organise your code, really. A common scenario
>is that you'd have a class Myclass, say, declared in the header
>myclass.hpp and with definitions in the compilation unit myclass.cpp.
>In which case, it seems appropriate to define and initialise your
>static members in myclass.cpp.
>
The question is how to define these initialise. You know, for a simple
member, I can
do something like:
int MyClass::myMember = 123;
but for complicated non-POD types, such as a std::vector, how do I
initialize it by
push_back() many elements into it? You see my problem? Thanks.
One way is to use a (static, possibly member) function to initialise your
variable:

// foo.hpp

#ifndef FOO_HPP
#define FOO_HPP

#include <vector>

class Foo
{
public:
static std::vector<intstatic_member;

static void static_initialiser(const int z);

Foo();

double y;
};

#endif

// foo.cpp

#include "foo.hpp"

#include <iostream>

std::vector<intFoo::static_member;

void Foo::static_initialiser(const int n)
{
std::cout << "Foo::static_initialiser()" << std::endl;
for (int i=0; i<n; ++i) static_member.push_back(i*i);
}

Foo::Foo()
{
std::cout << "Foo::Foo()" << std::endl;
}

// main.cpp

#include "foo.hpp"

#include <iostream>

int main()
{
const int n = 4;

Foo::static_initialiser(n);

Foo foo;

for (int i=0; i<n; ++i) std::cout << Foo::static_member[i] << '\n';

return 0;
}

// output

Foo::static_initialiser()
Foo::Foo()
0
1
4
9

Note that this won't work if Foo::static_member has to be const. To
handle that situation you can still use a static initialiser function,
but it must return the value you want assigned to your static member.

--
Lionel B
Lionel B
Guest
 
Posts: n/a
#4: Jul 15 '08

re: Initialize static members outside the class


On Tue, 15 Jul 2008 06:54:33 -0700, Steven Woody wrote:
Quote:
We must did the
following work in C for many many times:
>
// file: foo.c
>
static const int my_magic_code_table [] {
1,
9,
103,
2,
...
};
>
Now I sure you see what I was looking for is just a equivalent of above
in C++ as simple as we can approach.
Doh! Why didn't you just say that in the first place?

// foo.hpp:

class Foo
{
private:
static const int my_magic_code_table[];
public:
static const std::vector<intmy_magic_code_vector;
};

// foo.cpp:

const int Foo::my_magic_code_table[] =
{
1,
9,
103,
2
};

const std::vector<intFoo::my_magic_code_vector(
Foo::my_magic_code_table,
Foo::my_magic_code_table + sizeof(Foo::my_magic_code_table)/sizeof(int)
);

Although I'm not sure why you'd want a vector at all here

--
Lionel B
Steven Woody
Guest
 
Posts: n/a
#5: Jul 16 '08

re: Initialize static members outside the class


On Jul 15, 10:47 pm, Lionel B <m...@privacy.netwrote:
Quote:
On Tue, 15 Jul 2008 06:54:33 -0700, Steven Woody wrote:
Quote:
We must did the
following work in C for many many times:
>
Quote:
// file: foo.c
>
Quote:
static const int my_magic_code_table [] {
1,
9,
103,
2,
...
};
>
Quote:
Now I sure you see what I was looking for is just a equivalent of above
in C++ as simple as we can approach.
>
Doh! Why didn't you just say that in the first place?
>
// foo.hpp:
>
class Foo
{
private:
static const int my_magic_code_table[];
public:
static const std::vector<intmy_magic_code_vector;
>
};
>
// foo.cpp:
>
const int Foo::my_magic_code_table[] =
{
1,
9,
103,
2
>
};
>
const std::vector<intFoo::my_magic_code_vector(
Foo::my_magic_code_table,
Foo::my_magic_code_table + sizeof(Foo::my_magic_code_table)/sizeof(int)
);
>
Although I'm not sure why you'd want a vector at all here
Because what I given is merely an example, I made it to make the
sample code simple so that suitable to post on usenet. In practice,
my table not only contains plain integers, I contains NON-POD objects,
that's one of the reason I choice std::vector. I am looking for a
general solution.
James Kanze
Guest
 
Posts: n/a
#6: Jul 16 '08

re: Initialize static members outside the class


On Jul 15, 5:04 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
Steven Woody a écrit :
[...]
Quote:
There is still boost.assign:http://www.boost.org/doc/libs/1_35_0...doc/index.html
Quote:
If I understand correctly (I have never used it), this will give
something like:
Quote:
const std::vector<intmagic_code=list_of(1)(9)(103)(2)... (42);
If vector<>::push_back supported chaining, you wouldn't even
need that:

std::vector< int const magic
= std::vector< int >().push_back( 1 )
.push_back( 9 )... ;

(Of course, in this case, a somewhat shorter name would be
appreciated:-).)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
xtrigger303@gmail.com
Guest
 
Posts: n/a
#7: Jul 16 '08

re: Initialize static members outside the class


On 16 Lug, 13:02, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
James Kanze a écrit :
>
Quote:
On Jul 15, 5:04 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
Steven Woody a écrit :
>
Quote:
* * [...]
Quote:
There is still boost.assign:http://www.boost.org/doc/libs/1_35_0...doc/index.html
>
Quote:
Quote:
If I understand correctly (I have never used it), this will give
something like:
>
Quote:
Quote:
const std::vector<intmagic_code=list_of(1)(9)(103)(2)... (42);
>
Quote:
If vector<>::push_back supported chaining, you wouldn't even
need that:
>
The strcpy(), strcat, str... were designed for chaining but AFAIK, it is
rarely used that way. I guess it would also be marginally useful for
std::vector<>.
>
>
>
Quote:
* * std::vector< int const magic
* * * * = std::vector< int >().push_back( 1 )
* * * * * * * * * * * * * * * .push_back(9 )... ;
>
That's hideous. :)
>
--
Michael
Hi to all,
I use the following template to trigger static member functions (that
can be used to do any type of initalization ).
It always seemed to work in the few cases I've used it. The only doubt
is the constructor of the template, that refers to the static member
object to enforce instantiation. My doubt is that some compiler
optimization might throw that away. With gcc it never seems to happen
with any optimization.
Any comment?
Regards to all,
Francesco

#include <iostream>
#include <vector>

template< typename T >
class CAutoInitializer
{
protected:
// enforce sInit instantiation
CAutoInitializer() { return; sInit; }
private:
struct CInit { CInit() { T::StaticInitializer(); } };
static CInit sInit;
};

template< typename T >
typename CAutoInitializer< T >::CInit CAutoInitializer< T >::sInit;

//

class CSomething : CAutoInitializer< CSomething >
{
public:
// avoid static init fiasco
static std::vector< int & GetVec()
{ static std::vector< int sVec; return sVec; }

static void StaticInitializer()
{
std::cout << "Do anything you want here\n";
GetVec().push_back( 10 );
}
};

//

class CSomethingElse : CAutoInitializer< CSomethingElse >
{
public:
static void StaticInitializer()
{ std::cout << "Do something else here\n"; }
};

int main()
{
std::cout << "main\n";
CSomething obj1;
CSomethingElse obj2;
std::cin.get();
}

xtrigger303@gmail.com
Guest
 
Posts: n/a
#8: Jul 16 '08

re: Initialize static members outside the class


On 16 Lug, 13:42, xtrigger...@gmail.com wrote:
Quote:
On 16 Lug, 13:02, Michael DOUBEZ <michael.dou...@free.frwrote:
>
>
>
>
>
Quote:
James Kanze a écrit :
>
Quote:
Quote:
On Jul 15, 5:04 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
>Steven Woody a écrit :
>
Quote:
Quote:
* * [...]
>There is still boost.assign:http://www.boost.org/doc/libs/1_35_0...doc/index.html
>
Quote:
Quote:
>If I understand correctly (I have never used it), this will give
>something like:
>
Quote:
Quote:
>const std::vector<intmagic_code=list_of(1)(9)(103)(2)... (42);
>
Quote:
Quote:
If vector<>::push_back supported chaining, you wouldn't even
need that:
>
Quote:
The strcpy(), strcat, str... were designed for chaining but AFAIK, it is
rarely used that way. I guess it would also be marginally useful for
std::vector<>.
>
Quote:
Quote:
* * std::vector< int const magic
* * * * = std::vector< int >().push_back( 1 )
* * * * * * * * * * * * * * * .push_back( 9 )... ;
>
Quote:
That's hideous. :)
>
Quote:
--
Michael
>
Hi to all,
I use the following template to trigger static member functions (that
can be used to do any type of initalization ).
It always seemed to work in the few cases I've used it. The only doubt
is the constructor of the template, that refers to the static member
object to enforce instantiation. My doubt is that some compiler
optimization might throw that away. With gcc it never seems to happen
with any optimization.
Any comment?
Regards to all,
Francesco
>
#include <iostream>
#include <vector>
>
template< typename T >
class CAutoInitializer
{
protected:
* * // enforce sInit instantiation
* * CAutoInitializer() { return; sInit; }
private:
* * struct CInit { CInit() { T::StaticInitializer(); } };
* * static CInit sInit;
>
};
>
template< typename T >
typename CAutoInitializer< T >::CInit CAutoInitializer< T >::sInit;
>
//
>
class CSomething : CAutoInitializer< CSomething >
{
public:
* * // avoid static init fiasco
* * static std::vector< int & GetVec()
* * { static std::vector< int sVec; return sVec; }
>
* * static void StaticInitializer()
* * {
* * * * std::cout << "Do anything you want here\n";
* * * * GetVec().push_back( 10 );
* * }
>
};
>
//
>
class CSomethingElse : CAutoInitializer< CSomethingElse >
{
public:
* * static void StaticInitializer()
* * { *std::cout << "Do something else here\n"; }
>
};
>
int main()
{
* * std::cout << "main\n";
* * CSomething * * *obj1;
* * CSomethingElse *obj2;
* * std::cin.get();
>
>
>
}- Nascondi testo citato
>
- Mostra testo citato- Nascondi testo citato
>
- Mostra testo citato

Sorry,
the code I posted is broken if any other statically initialized object
will call GetVec() before the template static object is instantiated.
Fiasco!
The below code is more like it I think, but it's getting
convoluted.. :-(
Moreover it does not address multithreading issues.
Sorry again,
bye,
Francesco


#include <iostream>
#include <vector>

template< typename TDerivingClass, typename TStaticObject >
class CStaticInstanceAutoInit
{
public:
static TStaticObject & GetInstance()
{
static bool sInit = TDerivingClass::StaticInitializer();
return GetUnsafe();
}
protected:
static TStaticObject & GetUnsafe()
{
static TStaticObject sObj;
return sObj;
}
CStaticInstanceAutoInit() { return; sInit; }
private:
struct CInit { CInit()
{ CStaticInstanceAutoInit::GetInstance(); } };
static CInit sInit;
};

//
template< typename TDerivingClass, typename TStaticObject >
typename CStaticInstanceAutoInit< TDerivingClass, TStaticObject
Quote:
>::CInit
CStaticInstanceAutoInit< TDerivingClass, TStaticObject
Quote:
>::sInit;
//

class CSomething : public CStaticInstanceAutoInit< CSomething,
std::vector< int
{
public:
static bool StaticInitializer( void )
{
std::cout << "init static instance something\n";
GetUnsafe().push_back( 13 );
return true;
}
};

//

int main()
{
std::cout << "main\n";
CSomething obj1;
obj1.GetInstance();
obj1.GetInstance();
std::cin.get();
}
James Kanze
Guest
 
Posts: n/a
#9: Jul 16 '08

re: Initialize static members outside the class


On Jul 16, 1:02 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
James Kanze a écrit :
Quote:
Quote:
On Jul 15, 5:04 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
Steven Woody a écrit :
Quote:
Quote:
[...]
Quote:
There is still
boost.assign:http://www.boost.org/doc/libs/1_35_0...doc/index.html
Quote:
Quote:
Quote:
If I understand correctly (I have never used it), this will give
something like:
Quote:
Quote:
Quote:
const std::vector<intmagic_code=list_of(1)(9)(103)(2)... (42);
Quote:
Quote:
If vector<>::push_back supported chaining, you wouldn't even
need that:
Quote:
The strcpy(), strcat, str... were designed for chaining but
AFAIK, it is rarely used that way.
That's because the return value isn't the one you'd want to
chain.
Quote:
I guess it would also be marginally useful for std::vector<>.
Quote:
Quote:
std::vector< int const magic
= std::vector< int >().push_back( 1 )
.push_back( 9 )... ;
Quote:
That's hideous. :)
It's a more or less standard idiom in some OO circles. With
such a long and awkward name, it isn't really very pretty. But
globally, the policy of having all mutators return *this as a
non-const reference can occasionally be useful.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Steven Woody
Guest
 
Posts: n/a
#10: Jul 17 '08

re: Initialize static members outside the class


On Jul 16, 4:46 pm, James Kanze <james.ka...@gmail.comwrote:
Quote:
On Jul 15, 3:54 pm, Steven Woody <narkewo...@gmail.comwrote:
>
Quote:
On Jul 15, 9:11 pm, James Kanze <james.ka...@gmail.comwrote:
Quote:
On Jul 15, 12:05 pm, Steven Woody <narkewo...@gmail.comwrote:
>
[...]
>
Quote:
Anyway, methods like
Quote:
td::vector<intNonPOD::foo(SIZE,4.4)
or
Quote:
std::vector< int const Class::staticVect(
begin( something), end( something) )
simply don't work since they both get too much limitation. What I
need to put into the vector in initial time is very specific data,
filling the vector with many default value or a regular serial is not
enought.
>
But what is the specific data? If it's known at compile time
(or even if it's not---"something" can be an istream_iterator),
you can use the second. And if you don't know it until after
entering main, you can't make the vector const.
>
Quote:
If all above is what C++ can do for the specific problem, it
is a shame of the language, but I don't believe it can be
true.
>
Well, I've yet to find a case where the template constructor
taking two iterators wouldn't work (and the data was known
before hand, of course). And you can always use something like:
>
std::vector< int const Class::staticVector(
someFunctionReturningAVectorOfInt() ) ;
>
This seems interesting! I will try right now. And, in my real
program, the elements contained in the std::vector are actually
std::pair objects.
Closed Thread