473,735 Members | 2,102 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Mimicking Javas static class initializer in C++

Hi folks,

as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this evening:

Java has a nifty feature called a static class initializer - something
like this:

public class Foo
{
private static Vector<Thingxx;
static
{
xx = new Vector<Thing>(4 2);
for (int i=0; i < xx.size(); ++i)
xx.set(i, new Thing());
}
}

where the static{} block is called once (when the class is first used),
thus suitable for complex initializations of static members.

Now i would like to have this in C++, can this be done?
Here is my current approach:

VPNChannel.h
------------

class VPNChannel
{
static const int MAX_CHANNELS = 4;

// Bitmask of allocated channels
static uint32_t smAllocated_cha nnels_map;

//
// Vector holding all possible instances of VPNChannel
//
static VPNChannel *smInstances[MAX_CHANNELS];

//
// Static initializer
// This is kinda kludge to mimic Javas static {} class initializer
//
static uint32_t static_class_in itializer();
}


VPNChannel.cpp
--------------

#include "VPNChannel .h"

uint32_t VPNChannel::smA llocated_channe ls_map(static_c lass_initialize r());

uint32_t VPNChannel::sta tic_class_initi alizer()
{
for (int i=0; i < MAX_CHANNELS; ++i)
{
VPNChannel::smI nstances[i] = (VPNChannel *)NULL;
}
return (uint32_t)0;
}

with this idea in mind:

static_class_in itializer() is used to do complex initialization of an
static array, it returns a dummy zero value, so it can be used to
initialze another static variable (smAllocated_ch annels_map).
To my surprise, this compiles fine, but gives a linker error:

VPNChannel.o(.t ext+0x19):VPNCh annel.cpp: undefined reference to
`VPNChannel::sm Instances'
collect2: ld returned 1 exit status
(I'm using MinGW 3.4.2)

Any hint, what goes wrong here? Or maybe a better, more c++ish approach
to static initialization?

Cheers and Greetings
Andreas

Oct 27 '08 #1
11 5311
Andreas Wollschlaeger wrote:
as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this evening:

Java has a nifty feature called a static class initializer - something
like this:

public class Foo
{
private static Vector<Thingxx;
static
{
xx = new Vector<Thing>(4 2);
for (int i=0; i < xx.size(); ++i)
xx.set(i, new Thing());
}
}

where the static{} block is called once (when the class is first used),
thus suitable for complex initializations of static members.

Now i would like to have this in C++, can this be done?
Here is my current approach:

VPNChannel.h
------------

class VPNChannel
{
static const int MAX_CHANNELS = 4;

// Bitmask of allocated channels
static uint32_t smAllocated_cha nnels_map;

//
// Vector holding all possible instances of VPNChannel
//
static VPNChannel *smInstances[MAX_CHANNELS];

//
// Static initializer
// This is kinda kludge to mimic Javas static {} class initializer
//
static uint32_t static_class_in itializer();
}


VPNChannel.cpp
--------------

#include "VPNChannel .h"

uint32_t VPNChannel::smA llocated_channe ls_map(static_c lass_initialize r());

uint32_t VPNChannel::sta tic_class_initi alizer()
{
for (int i=0; i < MAX_CHANNELS; ++i)
{
VPNChannel::smI nstances[i] = (VPNChannel *)NULL;
}
return (uint32_t)0;
}

with this idea in mind:

static_class_in itializer() is used to do complex initialization of an
static array, it returns a dummy zero value, so it can be used to
initialze another static variable (smAllocated_ch annels_map).
To my surprise, this compiles fine, but gives a linker error:

VPNChannel.o(.t ext+0x19):VPNCh annel.cpp: undefined reference to
`VPNChannel::sm Instances'
collect2: ld returned 1 exit status
(I'm using MinGW 3.4.2)

Any hint, what goes wrong here? Or maybe a better, more c++ish approach
to static initialization?
------------------------------- Header:
class Foo
{
static vector<Thingxx;
public:
...
};

------------------------------- Implementation file:

vector<Thingyou r_static_initia liser()
{
vector<Thingv(4 2);
for (int i = 0; i < 42; ++i)
v[i] = ...; // whatever specific you want to get

return v;
}

vector<ThingFoo ::xx = your_static_ini tialiser();
....

(presuming you include all the relevant headers for 'vector', etc.)

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 27 '08 #2
Andreas Wollschlaeger schrieb:
Hi folks,

as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this evening:

Java has a nifty feature called a static class initializer - something
like this:

public class Foo
{
private static Vector<Thingxx;
static
{
xx = new Vector<Thing>(4 2);
for (int i=0; i < xx.size(); ++i)
xx.set(i, new Thing());
}
}

where the static{} block is called once (when the class is first used),
thus suitable for complex initializations of static members.

Now i would like to have this in C++, can this be done?
Here is my current approach:

VPNChannel.h
------------

class VPNChannel
{
static const int MAX_CHANNELS = 4;

// Bitmask of allocated channels
static uint32_t smAllocated_cha nnels_map;

//
// Vector holding all possible instances of VPNChannel
//
static VPNChannel *smInstances[MAX_CHANNELS];

//
// Static initializer
// This is kinda kludge to mimic Javas static {} class initializer
//
static uint32_t static_class_in itializer();
}


VPNChannel.cpp
--------------

#include "VPNChannel .h"

uint32_t VPNChannel::smA llocated_channe ls_map(static_c lass_initialize r());

uint32_t VPNChannel::sta tic_class_initi alizer()
{
for (int i=0; i < MAX_CHANNELS; ++i)
{
VPNChannel::smI nstances[i] = (VPNChannel *)NULL;
}
return (uint32_t)0;
}

with this idea in mind:

static_class_in itializer() is used to do complex initialization of an
static array, it returns a dummy zero value, so it can be used to
initialze another static variable (smAllocated_ch annels_map).
To my surprise, this compiles fine, but gives a linker error:

VPNChannel.o(.t ext+0x19):VPNCh annel.cpp: undefined reference to
`VPNChannel::sm Instances'
collect2: ld returned 1 exit status
(I'm using MinGW 3.4.2)

Any hint, what goes wrong here? Or maybe a better, more c++ish approach
to static initialization?

Cheers and Greetings
Andreas
You do not need to allocate every object with new in C++, so if you only
need a vector of Thing, use xx. If you need to allocate Thing on the
heap, use yy;
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector(); } yy;
};
xx.cpp:

#include <xx.h>

std::vector<Thi ngFoo::xx( 42 );
Foo::MyVector:: MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVector Foo::yy;

Lars
Oct 27 '08 #3
Lars Tetzlaff schrieb:
xx.cpp:

#include <xx.h>

std::vector<Thi ngFoo::xx( 42 );
Foo::MyVector:: MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVector Foo::yy;

Lars
Should be

push_back( new Thing() );

instead of

yy.push_back( new Thing() );
Lars
Oct 27 '08 #4
Andreas Wollschlaeger wrote:
Now i would like to have this in C++, can this be done?
One possible approach is to wrap the static data, which must be
initialized with code, inside a class/struct:

class Foo
{
struct XX
{
std::vector<Thi ngxx;

XX()
{
// Initialize 'xx' here.
// (You could also implement this in the compilation unit
// to reduce clutter in the header file.)
}
};

static XX xx;
};
Then in the compilation unit you define the XX instance:

Foo::XX Foo::xx; // Will be initialized with the XX constructor

Of course you'll have to access the vector with "xx.xx" from now on.
With a logical and modular naming scheme you can make it less ugly.
Oct 27 '08 #5
Lars Tetzlaff schrieb:
Andreas Wollschlaeger schrieb:
>Hi folks,

as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this evening:

Java has a nifty feature called a static class initializer - something
like this:
You do not need to allocate every object with new in C++, so if you only
need a vector of Thing, use xx. If you need to allocate Thing on the
heap, use yy;
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector(); } yy;
};
xx.cpp:

#include <xx.h>

std::vector<Thi ngFoo::xx( 42 );
Foo::MyVector:: MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVector Foo::yy;
Well, great, this was just what i have been looking for: encapsulating
the statics initialization in some inner class and its default
constructor - much more elegant and "cplusplusi sh" than my previous
attempt :-) Tx to you and the other folks, added me some more insight to
C++ this evening!

Cheers
Andreas

Oct 27 '08 #6
Andreas Wollschlaeger wrote:
Lars Tetzlaff schrieb:
>Andreas Wollschlaeger schrieb:
>>Hi folks,

as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this
evening:

Java has a nifty feature called a static class initializer - something
like this:
You do not need to allocate every object with new in C++, so if you only
need a vector of Thing, use xx. If you need to allocate Thing on the
heap, use yy;
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector(); } yy;
};
xx.cpp:

#include <xx.h>

std::vector<Th ingFoo::xx( 42 );
Foo::MyVector: :MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVecto r Foo::yy;

Well, great, this was just what i have been looking for: encapsulating
the statics initialization in some inner class and its default
constructor - much more elegant and "cplusplusi sh" than my previous
attempt :-) Tx to you and the other folks, added me some more insight to
C++ this evening!
I can see why that solution would look nice to a Java developer, but in
general, it's a bad idea to derive your own classes from the standard
ones; it is especially non-c++ish.

C++ methods aren't virtual by default; they're more like final methods
in Java. In particular, their destructors aren't virtual, so if ever an
instance of a derived type is deleted through a pointer to a base with a
non-virtual destructor, nasty things will happen. You're much better
off in this case with Victor or Juha's solutions, both of which are fine.

FWIW, most should-be-simple things aren't as complicated as this; there
are just a few "don't do thats" that you have to pick up when you get
started, and you happen to have gotten some mediocre advice (no offense,
Lars) right off the bat.
Oct 27 '08 #7
Jeff Schwab wrote:
Andreas Wollschlaeger wrote:
>Lars Tetzlaff schrieb:
>>>
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector(); } yy;
};
xx.cpp:

#include <xx.h>

std::vector<T hingFoo::xx( 42 );
Foo::MyVector ::MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVect or Foo::yy;

Well, great, this was just what i have been looking for: encapsulating
the statics initialization in some inner class and its default
constructor - much more elegant and "cplusplusi sh" than my previous
attempt :-) Tx to you and the other folks, added me some more insight
to C++ this evening!

I can see why that solution would look nice to a Java developer, but in
general, it's a bad idea to derive your own classes from the standard
ones; it is especially non-c++ish.
Unless you make the inheritance private, which would work equally well here:

static class MyVector : std::vector<Thi ng*>
{
public:
MyVector();
} yy;

--
Ian Collins
Oct 27 '08 #8
Ian Collins wrote:
Jeff Schwab wrote:
>Andreas Wollschlaeger wrote:
>>Lars Tetzlaff schrieb:
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector() ; } yy;
};
xx.cpp:

#include <xx.h>

std::vector< ThingFoo::xx( 42 );
Foo::MyVecto r::MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVecto r Foo::yy;
Well, great, this was just what i have been looking for: encapsulating
the statics initialization in some inner class and its default
constructor - much more elegant and "cplusplusi sh" than my previous
attempt :-) Tx to you and the other folks, added me some more insight
to C++ this evening!
I can see why that solution would look nice to a Java developer, but in
general, it's a bad idea to derive your own classes from the standard
ones; it is especially non-c++ish.
Unless you make the inheritance private, which would work equally well here:

static class MyVector : std::vector<Thi ng*>
{
public:
MyVector();
} yy;
True that. :)
Oct 27 '08 #9
Jeff Schwab schrieb:
Andreas Wollschlaeger wrote:
>Lars Tetzlaff schrieb:
>>Andreas Wollschlaeger schrieb:
Hi folks,

as the subject says, i'm a poor Java programmer trying to transfer some
of his wisdom into C++ world... here is what im trying to do this
evening:

Java has a nifty feature called a static class initializer - something
like this:
You do not need to allocate every object with new in C++, so if you only
need a vector of Thing, use xx. If you need to allocate Thing on the
heap, use yy;
xx.h:

#include <vector>

class Thing
{
};

class Foo
{
private:
static std::vector<Thi ngxx;
static class MyVector : public std::vector<Thi ng*>{ public:
MyVector(); } yy;
};
xx.cpp:

#include <xx.h>

std::vector<T hingFoo::xx( 42 );
Foo::MyVector ::MyVector()
{
for( int i = 0; i<42; ++i ) {
yy.push_back( new Thing() );
}
}

Foo::MyVect or Foo::yy;

Well, great, this was just what i have been looking for: encapsulating
the statics initialization in some inner class and its default
constructor - much more elegant and "cplusplusi sh" than my previous
attempt :-) Tx to you and the other folks, added me some more insight
to C++ this evening!

I can see why that solution would look nice to a Java developer, but in
general, it's a bad idea to derive your own classes from the standard
ones; it is especially non-c++ish.

C++ methods aren't virtual by default; they're more like final methods
in Java. In particular, their destructors aren't virtual, so if ever an
instance of a derived type is deleted through a pointer to a base with a
non-virtual destructor, nasty things will happen. You're much better
off in this case with Victor or Juha's solutions, both of which are fine.
Since the destruction of yy happens in the implementation file the type
is known to the compiler and the right destructor is called. The class
was ment *only* to initialize the static member. Generally I would agree
to your comment but not in the situation of initializing a static member
or a local variable.
>
FWIW, most should-be-simple things aren't as complicated as this; there
are just a few "don't do thats" that you have to pick up when you get
started, and you happen to have gotten some mediocre advice (no offense,
Lars) right off the bat.
Lars
Oct 28 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
4622
by: Qin Chen | last post by:
I will present very long code, hope someone will read it all, and teach me something like tom_usenet. This question comes to me when i read <<Think in C++>> 2nd, chapter 10 , name control, section "Static initialization dependency". There is a example to show how to solve the prolem involved with a technique first poineered by Jerry Schwarz while creating the iostream library (because the definitions for cin, cout, and cerr are static...
14
2869
by: Mike Hewson | last post by:
Have been researching as to why: <example 1> class ABC { static const float some_float = 3.3f; }; <end example 1>
5
3084
by: Tina | last post by:
I'm using C# 1.1.............. I add new Class item to my project. It's created as class Math I change it to public static class Math I get an error saying that "The modifier 'static' is not valid for this item. Why? Are static classes not allowed??
12
3440
by: Hemanth | last post by:
Hi, I have a base class with a static constructor and some abstract methods. Derived classes implement these methods. From articles on the web, it appears that there is no guarentee that this static constructor of the base class would be invoked even if a an object of the derived class is created. Is this correct ? Is there any way to ensure the base class's static constructor is invoked before the derived class instance is constructed ?...
12
2904
by: Philip Potter | last post by:
I'm reading the comp.lang.c++ faq and, though it is incredibly clear and lucid in many points, I am completely confused by question 29.6: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.6 "Here is another even more common example: class Fred { public: ... private:
8
8930
by: Per Bull Holmen | last post by:
Hey Im new to c++, so bear with me. I'm used to other OO languages, where it is possible to have class-level initialization functions, that initialize the CLASS rather than an instance of it. Like, for instance the Objective-C method: +(void)initialize Which has the following characteristics: It is guaranteed to be run
6
3564
by: Marvin Barley | last post by:
I have a class that throws exceptions in new initializer, and a static array of objects of this type. When something is wrong in initialization, CGI program crashes miserably. Debugging shows uncaught exception. How to catch an exception that happened before main() try { ... } catch (...) { ... } block? Is there a way?
1
3533
by: Sandro Bosio | last post by:
Hello everybody, my first message on this forum. I tried to solve my issue by reading other similar posts, but I didn't succeed. And forgive me if this mail is so long. I'm trying to achieve the following (with incomplete succes): I want in a given namespace Parameters a list of "initializers" (which are objects derived from a simple interface that can be implemented anywhere, and are used to define which parameters the program will take at...
15
7868
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
0
9466
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9253
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9201
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6049
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4564
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4823
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3277
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2740
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2190
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.