[comp.lang.c++] static member data initialization query

lef@nlm-vax.UUCP (05/14/87)

Hello,  I am rather new to C++ and have a question about the
initialization of static member data.  Given a class that has
some static data associated with it, that is, data shared
by all instances rather than replicated, what is the best way
to initialize that data?  The following was my first thought

	class date {
		static char *mmm[12]={"jan","feb","mar",...};
		...
	}

but this generates a compiler message "initialization of static members
unimplemented" (or something like that).   I can't seem to see how
to initialize the data with a constructor given that you only
want it to happen once, not once for every instance.

The only other alternative I can see is to use static global data.
Am I missing something or is this the preferred way to do this?

thanks, fitz

l e fitzpatrick
national library of medicine
bethesda, md

jon@oddhack.UUCP (05/20/87)

In article <2464@nlm-vax.arpa> lef@nlm-vax.arpa (Larry Fitzpatrick) writes:
>Hello,  I am rather new to C++ and have a question about the
>initialization of static member data.  Given a class that has
>some static data associated with it, that is, data shared
>by all instances rather than replicated, what is the best way
>to initialize that data?  The following was my first thought
>
>	class date {
>		static char *mmm[12]={"jan","feb","mar",...};
>		...
>	}
>
>but this generates a compiler message "initialization of static members
>unimplemented" (or something like that).   I can't seem to see how
>to initialize the data with a constructor given that you only
>want it to happen once, not once for every instance.

	Here's a kludgy way of doing what you want. It relies on the 
implementation of static class members as global variables, which are 
guaranteed to be initialized to 0. Basically in addition to the data
you want, you add a static flag which says that the static data has
not yet been initialized. Then you let the constructor do it. Note that
8.5.1 in the book says ``No initializer can be specified for a static
member, and it cannot be of a class with a constructor.'' Presumably
the latter restriction has been removed at some point, since the
following example compiles and runs fine under 1.1:


#include <stream.h>

class foo {
    static int initialized;	// Flag; if non-zero, data has been initialized
    static double data[2];	// Data to be initialized on first constructor
public:
    foo();
};

main() {
    foo a, b;
}

foo::foo() {
    if (!initialized) {
	cout << "foo.data is not initialized\n";
	data[0] = 3.1415926;
	data[1] = 2.7182818;
	initialized = 1;	// Flag so we don't do this more than once
    } else {
	cout << "foo.data is already initialized\n";
    }
}

	When run, this produces

foo.data is not initialized		(when constructor for a is called)
foo.data is already initialized		(when constructor for b is called)

	The overhead of checking the flag is minimal compared to the call
and (sometimes) allocation overhead for class members. For your example, 
you would have to do something like define the month names in a external 
array (or static to the constructor), and make the static member of class 
date a reference or pointer to this data.

    -- Jon Leech (jon@csvax.caltech.edu || ...seismo!cit-vax!jon)
    Caltech Computer Science Graphics Group
    __@/

jss@hector..UUCP (Jerry Schwarz) (05/21/87)

In article <2755@cit-vax.Caltech.Edu> jon@oddhack.Caltech.EDU (Jon Leech) writes:
>
>Note that
>8.5.1 in the book says ``No initializer can be specified for a static
>member, and it cannot be of a class with a constructor.'' 
>

This has frequently been misread as meaning that there cannot be
constructor in the class containing the static.  What it really says
(at least what Bjarne intended it to say) is that the static member
cannot have a type that has a constructor.

For example

	class S { static int x ; S() ; } ;

is ok, but (given the above) 
	
	class T { static S s ; }   ;

is not.  

Jerry Schwarz