473,581 Members | 2,783 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

static class initialization functions in c++?

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)initiali ze

Which has the following characteristics : It is guaranteed to be run
before the first instance of that particular class is created. It is a
static member function, which otherwise operates the same way as any
other such functions: It can be overridden by subclasses, and the
overridden can call the superclass' implementation if needed, etc...

I have been looking, but not found an equivalent in c++. Is there one?

Per
Dec 25 '06 #1
8 8916

"Per Bull Holmen" <pb******@yahoo .comwrote in message
news:1h******** *************** *******@yahoo.c om...
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.
In C++, only a object can be initialized. A class is not an object.
Like, for instance
the Objective-C method:

+(void)initiali ze

Which has the following characteristics : It is guaranteed to be run
before the first instance of that particular class is created.
A C++ class can contain static member objects, which are initialized
before 'main()' begins. If there is more than one static (member or
nonmember) object in the program, the order of their initialization
is not specified by the language.
>It is a
static member function,
In C++, only one member function of a class can initialize that
class's data members: the constructor.
which otherwise operates the same way as any
other such functions: It can be overridden by subclasses, and the
overridden can call the superclass' implementation if needed, etc...
A constructor can not be overridden. Creation of an object of a derived
type will automatically cause its base class' constructor to be invoked.
I have been looking, but not found an equivalent in c++. Is there one?
class B
{
static int i;
int j;
public:
B(int arg = 0) : j(arg) /* constructor */
{
}
};

int B::i = 42; /* initialize B::i with the value 42 */
class D : public B
{
static int m;
int k;
public:
D(int Bval, int kval) : B(Bval), k(kval) /* constructor */
{
}
};

int D::m = 10; /* initialize D::m with the value 10 */

int main()
{
B b_obj(99); /* create an object of type 'B', and
intialize it's member 'j' with the
value 99 */

D d_obj(25, 32); /* create an object of type 'D', initialize
its base portion (via its constructor 'B::B()')
with value 25, and initialize its member 'k' with
value 32 */
return 0;
}

If you tell us more specifically what you're trying to do,
perhaps we can offer more specific advice.

Which C++ book(s) are you reading?
-Mike
Dec 25 '06 #2
Mike Wahler <mk******@mkwah ler.netwrote:

If you tell us more specifically what you're trying to do,
perhaps we can offer more specific advice.
I'm trying to write a base class for scriptable objects. The subclasses
of this class hold a set of properties that must be identified by name
(a string), that can be retrieved or set by a script. But never mind the
scripting, I just explain it so you can see why the properties must be
identified by names. When the member functions

int Scriptable::lua GetProperty( lua_State *lua, string &propertyNam e )
int Scriptable::lua SetProperty( lua_State *lua, string &propertyNam e )

are called on the scriptable objects, the respective subclasses must be
free to implement the getting and setting of these properties
themselves, so it's not possible to just let these properties be held by
some hashtable. It would be nice to let the subclass just forward the
requests to the following member functions:

int Scriptable::lua GetProperty( lua_State *lua, int propertyCode )
int Scriptable::lua SetProperty( lua_State *lua, int propertyCode )

which take an int code (i.e. an enum) instead of an action name, cause
then I can just use switch statements like this:

switch( propertyCode ) {
case HEIGHT_PROPERTY :
// perform code to get/set height
case WIDTH_PROPERTY:
// etc...
}

My problem is the following: I thought it would be a bad idea to
hardcode all property names and respective codes in the base class. So,
I thought I'd let the base class hold a registry of property names and
codes in a hashtable, as a static member shared by subclasses. Then, any
subclass that adds new properties, can call the function:

void Scriptable::reg isterPropertyCo de( string &name, int code ) {
properties.put( name, code );
}

Where properties is the hashtable. In the main other language I've been
programming in (Objective-C), I would simply make the class initializer
call a static member function, declared something like this:

class Scriptable {

/.../

static void registerPropert ies();

/.../
};

So that any subclass can override this to add their own properties. I
thought the cleanest way to do this, would be to make the class
guarantee that the properties were registered before any instances of
the class were set into action. I might do it in the constructors,
though, but I thought it wouldn't be optimal. I'm sure there's a
workaround for this specific problem, but I'm trying to learn how to
solve this type of problems in the future
Which C++ book(s) are you reading?
"Core C++ A Software Engineering Approach" by Victor Shtern.

Per
Dec 25 '06 #3
Mike Wahler <mk******@mkwah ler.netwrote:

If you tell us more specifically what you're trying to do,
perhaps we can offer more specific advice.
I'm trying to write a base class for scriptable objects. The subclasses
of this class hold a set of properties that must be identified by name
(a string), that can be retrieved or set by a script. But never mind the
scripting, I just explain it so you can see why the properties must be
identified by names. When the member functions

int Scriptable::lua GetProperty( lua_State *lua, string &propertyNam e )
int Scriptable::lua SetProperty( lua_State *lua, string &propertyNam e )

are called on the scriptable objects, the respective subclasses must be
free to implement the getting and setting of these properties
themselves, so it's not possible to just let these properties be held by
some hashtable. It would be nice to let the base class just forward the
requests to the following member functions:

int Scriptable::lua GetProperty( lua_State *lua, int propertyCode )
int Scriptable::lua SetProperty( lua_State *lua, int propertyCode )

which take an int code (i.e. an enum) instead of an action name, cause
then I can just use switch statements like this:

switch( propertyCode ) {
case HEIGHT_PROPERTY :
// perform code to get/set height
case WIDTH_PROPERTY:
// etc...
}

My problem is the following: I thought it would be a bad idea to
hardcode all property names and respective codes in the base class. So,
I thought I'd let the base class hold a registry of property names and
codes in a hashtable, as a static member shared by subclasses. Then, any
subclass that adds new properties, can call the function:

void Scriptable::reg isterPropertyCo de( string &name, int code ) {
properties.put( name, code );
}

Where properties is the hashtable. In the main other language I've been
programming in (Objective-C), I would simply make the class initializer
call a static member function, declared something like this:

class Scriptable {

/.../

static void registerPropert ies();

/.../
};

So that any subclass can override this to add their own properties. I
thought the cleanest way to do this, would be to make the class
guarantee that the properties were registered before any instances of
the class were set into action. I might do it in the constructors,
though, but I thought it wouldn't be optimal. I'm sure there's a
workaround for this specific problem, but I'm trying to learn how to
solve this type of problems in the future
Which C++ book(s) are you reading?
"Core C++ A Software Engineering Approach" by Victor Shtern.

Per
Dec 25 '06 #4
Per Bull Holmen wrote:
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)initiali ze

Which has the following characteristics : It is guaranteed to be run
before the first instance of that particular class is created. It is a
static member function, which otherwise operates the same way as any
other such functions: It can be overridden by subclasses, and the
overridden can call the superclass' implementation if needed, etc...

I have been looking, but not found an equivalent in c++. Is there one?

Per
such a syntax does not exist in C++ but you can device the dummy
variable initialization technique:

class myclass{
private:
struct initializer{
initializer(){
//do write initialization code here
};//end initializer()
};//end struct initializer

friend struct initializer; /*grant initializer the permission to
axcess private members of mystruct*/

static initializer unused; //unused variable

}; //end class myclass

myclass::initia lizer myclass::unused (); //invoke initialization

Dec 25 '06 #5
terminator <fa***********@ gmail.comwrote:
such a syntax does not exist in C++ but you can device the dummy
variable initialization technique:

class myclass{
private:
struct initializer{
initializer(){
//do write initialization code here
};//end initializer()
};//end struct initializer

friend struct initializer; /*grant initializer the permission to
axcess private members of mystruct*/

static initializer unused; //unused variable

}; //end class myclass

myclass::initia lizer myclass::unused (); //invoke initialization
Thanks.

I couldn't get the above code to work, I got a compile-time error. With
my present knowledge of c++, I couldn't figure out what was wrong, but I
tried to use the same idea slightly differently:

class myclass {

static bool initialized; //unused variable

static bool initialize() {
printf( "Init\n" );
return( true );
}

public:
myclass() {}

}; //end class myclass

bool myclass::initia lized = myclass::initia lize(); //invoke
initialization

This worked fine, but sometimes one might want to be guaranteed that all
superclasses' initializers get invoked before a subclass' initializer. I
couldn't do that without changing the constructors a bit, because the
order of initialization of static class members is undefined, and I
can't rely on some static bool initialized value being false if it
hasn't been - well - initialized. With the following code it worked:

class myclass {

static bool classInitialize d;

static void initializeClass () {
printf( "Init base\n" );
classInitialize d = true;
}

public:
myclass() {
if( ! classInitialize d )
initializeClass ();
}

}; //end class myclass

bool myclass::classI nitialized = false;

class subclass : myclass {

static bool classInitialize d;

static void initializeClass () {
printf( "Init sub\n" );
classInitialize d = true;
}

public:
subclass() {
if( ! classInitialize d )
initializeClass ();
}

}; //end class myclass

bool subclass::class Initialized = false;

Since myclass' constructor gets implicitly invoked when a new instance
of subclass is created, this should guarantee that all superclasses get
initialized first. It seems that when an instance of subclass invokes
myclass' constructor, it uses the myclass::classI nitialized variable
rather than subclass::class Initialized. Am I relying on undefined
behaviour here, or is this part of the c++ standard?

Per
Dec 25 '06 #6
Per Bull Holmen wrote:
Mike Wahler <mk******@mkwah ler.netwrote:

If you tell us more specifically what you're trying to do,
perhaps we can offer more specific advice.

I'm trying to write a base class for scriptable objects. The subclasses
of this class hold a set of properties that must be identified by name
(a string), that can be retrieved or set by a script. But never mind the
scripting, I just explain it so you can see why the properties must be
identified by names. When the member functions

int Scriptable::lua GetProperty( lua_State *lua, string &propertyNam e )
int Scriptable::lua SetProperty( lua_State *lua, string &propertyNam e )

are called on the scriptable objects, the respective subclasses must be
free to implement the getting and setting of these properties
themselves, so it's not possible to just let these properties be held by
some hashtable. It would be nice to let the base class just forward the
requests to the following member functions:

int Scriptable::lua GetProperty( lua_State *lua, int propertyCode )
int Scriptable::lua SetProperty( lua_State *lua, int propertyCode )

which take an int code (i.e. an enum) instead of an action name, cause
then I can just use switch statements like this:

switch( propertyCode ) {
case HEIGHT_PROPERTY :
// perform code to get/set height
case WIDTH_PROPERTY:
// etc...
}

My problem is the following: I thought it would be a bad idea to
hardcode all property names and respective codes in the base class. So,
I thought I'd let the base class hold a registry of property names and
codes in a hashtable, as a static member shared by subclasses.
You want to respect the relationship between the base class and its
subclasses.
Not just use the base class as a universal repository of static
properties.

Its completely conceivable to have some static repository of properties
in your program, but don't put it in your base class. Let a static
collection of properties live outside of the class. That way, you can
create different Scriptable derivatives based on different sets of
static data.

See if the code below helps. Note that std::map is not neccessarily a
solution here. Its just a suggestion (std::maps load reletively slowly
but search/find is infinitely faster that an array with op[]). You
might also consider using a reference to a static collection in your
base class with a set of Scriptables referring to one static map
collection and another set of Scriptables referring to some other
static collection. The possibilities are endless.

Note the ctors that take an external std::map collection as a
parameter.

#include <iostream>
#include <ostream>
#include <map>

class Base
{
std::map< std::string, int properties;
public:
Base() : properties() { }
Base(std::map< std::string, int >& r_m) : properties(r_m) { }
Base(const Base& copy) { properties = copy.properties ; }
virtual ~Base() { }
/* virtual member functions */
virtual void /* staggered to fit */
registerPropert iesCode(const std::string&, const int) = 0;
virtual int
getProperty(con st std::string& r_s) const;
/* global friend op<< */
friend std::ostream&
operator<<(std: :ostream&, const Base&);
};

void
Base::registerP ropertiesCode(c onst std::string& r_s, const int n)
{
properties.inse rt( std::make_pair< std::string, int >(r_s, n) );
}

int
Base::getProper ty(const std::string& r_s) const
{
typedef std::map< std::string, int >::const_iterat or MIter;
MIter found = properties.find ( r_s );
if(found != properties.end( ))
return (*found).second ;
else
return -1;
}

std::ostream& operator<<(std: :ostream& os, const Base& r_b)
{
typedef std::map< std::string, int >::const_iterat or MIter;
for( MIter miter = r_b.properties. begin();
miter != r_b.properties. end();
++miter )
{
os << "property: " << (*miter).first;
os << "\t" << "value: " << (*miter).second ;
os << "\n";
}
return os;
}

class Scriptable : public Base
{
public:
Scriptable() { }
Scriptable(std: :map< std::string, int >& m) : Base(m) { }
Scriptable(cons t Scriptable& copy) : Base(copy)
{
}
/* required virtuals */
void
registerPropert iesCode(const std::string& r_s, const int n)
{
Base::registerP ropertiesCode(r _s, n);
}
};

int main()
{
Scriptable instance;
instance.regist erPropertiesCod e("HEIGHT_PROPE RTY", 60);
instance.regist erPropertiesCod e("WIDTH_PROPER TY", 100);
instance.regist erPropertiesCod e("XCOORD_PROPE RTY", 10);
instance.regist erPropertiesCod e("YCOORD_PROPE RTY", 0);

std::cout << "get WIDTH_PROPERTY: ";
std::cout << instance.getPro perty("WIDTH_PR OPERTY");
std::cout << std::endl;
std::cout << "get BOGUS_PROPERTY: ";
std::cout << instance.getPro perty("BOGUS_PR OPERTY");
std::cout << std::endl;

std::cout << instance << std::endl; // friend op<<

Scriptable copy(instance); // copy the properties
std::cout << copy << std::endl;

static std::map< std::string, int mycollection;
mycollection.in sert(
std::make_pair< std::string, int >("FIRST_PROPER TY", 1) );
mycollection.in sert(
std::make_pair< std::string, int >("SECOND_PROPE RTY", 2) );
mycollection.in sert(
std::make_pair< std::string, int >("THIRD_PROPER TY", 3) );

Scriptable another(mycolle ction);
std::cout << another << std::endl;
}

/*
get WIDTH_PROPERTY: 100
get BOGUS_PROPERTY: -1 // probably not appropriate
property: HEIGHT_PROPERTY value: 60
property: WIDTH_PROPERTY value: 100
property: XCOORD_PROPERTY value: 10
property: YCOORD_PROPERTY value: 0

property: HEIGHT_PROPERTY value: 60
property: WIDTH_PROPERTY value: 100
property: XCOORD_PROPERTY value: 10
property: YCOORD_PROPERTY value: 0

property: FIRST_PROPERTY value: 1
property: SECOND_PROPERTY value: 2
property: THIRD_PROPERTY value: 3
*/

Merry Xmas to all !!

Dec 25 '06 #7
Per Bull Holmen wrote:
terminator <fa***********@ gmail.comwrote:
such a syntax does not exist in C++ but you can device the dummy
variable initialization technique:

class myclass{
private:
struct initializer{
initializer(){
//do write initialization code here
};//end initializer()
};//end struct initializer

friend struct initializer; /*grant initializer the permission to
axcess private members of mystruct*/

static initializer unused; //unused variable

}; //end class myclass

myclass::initia lizer myclass::unused (); //invoke initialization

Thanks.

I couldn't get the above code to work, I got a compile-time error.
I coud not either.this seems to be my mistake in syntax.but I removed
the braces in the last line and it compiled and worked.so change that
line to this:

/* outside class declaration of static member variable :constructing it
with default (none parameterd) constructor */
myclass::initia lizer myclass::unused ;
/*myclass::initi alizer myclass::unused (); */ /*do not uncomment:
error on this line*/

In C++ you must declare static member variables outside the class and
select the constructor that initializes it.try this:

class myclass{
protected:
struct initializer{
initializer(){
printf("initial ize default\n");
};//end initializer()

initializer(int data){
printf("initial ize with: %d\n",data);
};//end initializer(int )

};//end struct initializer

friend struct initializer; /*grant initializer the permission to
axcess private members of mystruct*/

private:
static initializer svar1,svar2; //static variables

}; //end class myclass
myclass::initia lizer myclass::svar1 /* default constructor
*/
,myclass::svar2 (13); /*parametered
constructor*/

struct subclass:
public myclass //inherit publicly
{// begin subclass

private:

typedef myclass::initia lizer InitializerBase ; /*
declare a private nested type*/

protected:

class initializer:
private InitializerBase //inherit privately
{// begin class initializer

public:

initializer() {printf("subcla ss\n");};

initializer(cha r c) :
InitializerBase (c) /*choose parametered version
of base constructor*/
{// begin initializer (char)

printf("subclas s with %c\n",c);

};// end initializer (char)

};// end class initializer

public:

static initializer sub1,sub2; //static stuff

};// end subclass

subclass::initi alizer subclass::sub1 /* default constructor */
,subclass::sub2 ('A');/*parametered
constructor*/

For the sake of implicit call to base class static constructor , have
every derived class`s initializer type to be a subclass of that of the
base class(in this case "struct initializer" must be not private ; so
have it protected).You can also put some of your static member
variables in initializer ,this increases encapsulation and "unused"
will not be unused any more .
With
my present knowledge of c++, I couldn't figure out what was wrong, but I
tried to use the same idea slightly differently:

class myclass {

static bool initialized; //unused variable

static bool initialize() {
printf( "Init\n" );
return( true );
}

public:
myclass() {}

}; //end class myclass

bool myclass::initia lized = myclass::initia lize(); //invoke
initialization

This worked fine, but sometimes one might want to be guaranteed that all
superclasses' initializers get invoked before a subclass' initializer. I
couldn't do that without changing the constructors a bit, because the
order of initialization of static class members is undefined, and I
can't rely on some static bool initialized value being false if it
hasn't been - well - initialized. With the following code it worked:

class myclass {

static bool classInitialize d;

static void initializeClass () {
printf( "Init base\n" );
classInitialize d = true;
}

public:
myclass() {
if( ! classInitialize d )
initializeClass ();
}

}; //end class myclass

bool myclass::classI nitialized = false;

class subclass : myclass {

static bool classInitialize d;

static void initializeClass () {
printf( "Init sub\n" );
classInitialize d = true;
}

public:
subclass() {
if( ! classInitialize d )
initializeClass ();
}

}; //end class myclass

bool subclass::class Initialized = false;

Since myclass' constructor gets implicitly invoked when a new instance
of subclass is created, this should guarantee that all superclasses get
initialized first. It seems that when an instance of subclass invokes
myclass' constructor, it uses the myclass::classI nitialized variable
rather than subclass::class Initialized. Am I relying on undefined
behaviour here, or is this part of the c++ standard?

Per
you are paying an unnecessary runtime overhead for checking
"classInitializ ed" for every instance of myclass.

Dec 26 '06 #8
terminator <fa***********@ gmail.comwrote:
you are paying an unnecessary runtime overhead for checking
"classInitializ ed" for every instance of myclass.
I know. Not bad for a complete c++ newbie, though?? :)

Thanks for your help, I'll try your code later.

Per
Dec 26 '06 #9

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

Similar topics

2
2820
by: tekenenSPAM | last post by:
I know that one cannot cast a non-static member function to a void *. (http://users.utu.fi/sisasa/oasis/cppfaq/pointers-to-members.html) However, I have a case where I need to call a certain member function based on a value passed into another function. Since there are a large number of these values and therefore a large number of...
1
3007
by: Piotr Sawuk | last post by:
just a quick question out of curiosity: how to initialize const arrays? struct srat { long num; ulong den; srat(){} } struct collisions
8
3004
by: Robert A Riedel | last post by:
I have an application that requires a DLL and an executable that uses the DLL, both of which were implemented in Visual C++ using unmanged code. Both the executable and the DLL are linked with functions that are stored in a static library. During initialization of the executable, classes and static globals within functions linked from the...
4
3097
by: mnowosad | last post by:
As far I know, static variables are tied to AppDomain scopes. So, every time an executing code within an AppDomain references a class for the the first time since the AppDomain was created/loaded, the .NET executes the assignments done in the class static variables declarations and runs the static constructor of that class. So, I expected...
10
4191
by: n.torrey.pines | last post by:
Are global variables (and const's) guaranteed to be initialized before static class members (and methods) ? const int x = 19907; int get_x() { return x; } // another compilation unit: int get_x();
6
3206
by: darkshaddow | last post by:
I am having trouble with a LNK2019 on a member function. Here is the error: main.obj : error LNK2019: unresolved external symbol "public: void __thiscall Stat::openFile(char *)" (?openFile@Stat@@QAEXPAD@Z) referenced in function _main As all functionality is made by me or uses simply c++'s main libraries through its header files, there was...
9
8870
by: Jess | last post by:
Hello, I was told that if I declare a static class constant like this: class A{ static const int x = 10; }; then the above statement is a declaration rather than a definition. As I've *defined* "x"'s value to be 10, isn't above statement a
3
2138
by: Thomas Troeger | last post by:
Hello, I have a class that looks like this: class A(object): def __init__(self, a=0, b=1): self.a, self.b=a, b def __str__(self): return "%s(%d,%d)" % (type(a).__name__, self.a, self.b)
11
5299
by: Andreas Wollschlaeger | last post by:
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 {
0
7876
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8156
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. ...
0
8310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7910
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...
0
6563
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5366
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...
1
2307
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
1
1409
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1144
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...

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.